本帖最后由 kukumh 于 2009-08-25 09:21:44 编辑

解决方案 »

  1.   

    应该是sleep之后wakeup的时候又重新执行一遍吧,不太清楚,等高手
      

  2.   

     这里  Thread.Sleep(200); 没把法把定时期休眠,只不过这个tmrShowData_Tick执行的时候休眠0.2秒
      tmrShowData_Tick还是按照100的间隔继续执行
      

  3.   

    应该是 Thread.Sleep(200);这个问题
      

  4.   

    Thread.Sleep(200);
    只是把当前的线程暂停了,但是不会暂停Timer的执行。Timer仍是100后开始一个新的线程执行Tick事件。
      

  5.   

    不奇怪啊,你设置100毫秒触发一次的,而你一次执行响应中会等待200毫秒,所以在输出“2.”之前第二次执行被触发。
    Timer定时器是异步运行的,它的计时是在另一个线程中运行的,时间间隔一到,就委托主线程调用定时事件,而那些事件是委托主线程调用的,不是强制要执行的,所以是在主线程里排队执行,但遇到了Thread.Sleep(200);后,主线程空闲,第二次的定时事件就插班了,所以顺序就打乱了。
      

  6.   

    private void tmrShowData_Tick(object sender, EventArgs e)
            {
                Trace.WriteLine("1." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Thread.Sleep(200);
    ********************************************************************
    大哥,你的tmrShowData并没有停止计时呀,你的tmrShowData100毫秒执行一次,你一睡就睡了200ms,
    怎么能对呢?
    ********************************************************************
                Trace.WriteLine("2." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Trace.WriteLine((x++).ToString());
            }
      

  7.   


    是排队执行的,只要你的一次触发事件中没有任何停顿,就不会发生插班现象,而所有没来得及执行的触发事件将会进入Windows的消息队列排队,等待主线程空闲时执行。
      

  8.   

        1.35:156 //100个间隔
        1.35:156 //100个间隔没有完成,有一个线程启动执行tick事件
        2.35:359 //
        0 
        2.35:359 //这个该如何解释?
        0 
      

  9.   

    很好,但是如果 我把 sleep换成一个较为复杂的函数,执行时间要超过100会怎么样?
      

  10.   

    建议楼主把timer 的 代码贴上来,才好分析
      

  11.   


                Trace.WriteLine("2." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Trace.WriteLine((x++).ToString());
    你看了很不会分析别人的回复内容,我都说得很清楚了,你这里两句之间没有停顿,只要保证“一次触发事件中没有任何停顿,就不会发生插班现象”——我12楼的回复
      

  12.   

            private void tmrShowData_Tick(object sender, EventArgs e)
            {
                ShowCurves();
            }其中ShowCurves()是一个较为复杂的函数,执行时间要超过100,我想知道这个时候tmrShowData_Tick的函数是怎么执行的
      

  13.   

    感觉:
        1.35:156 
        1.35:156 
    //以上有Trace.WriteLine("1." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);产生的    2.35:359 
        0 
        2.35:359 
        0 
    //由 Trace.WriteLine("2." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Trace.WriteLine((x++).ToString());产生的但是为什么是双份呢?
      

  14.   


    这还不简单,你写个10万次循环,执行些简单的操作,比如乘法,但要注意到int最大值之前重新初始化下。循环次数增加,需要的时间就越长。自己看看会怎么样就知道了。
      

  15.   

    猜测 ShowCurves() 就是产生双份 的原因
      

  16.   


            private void tmrShowData_Tick(object sender, EventArgs e)
            {
                tmrShowData.Enabled = false;
                Trace.WriteLine("1." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Trace.WriteLine("2." + System.DateTime.Now.Second + ":" + System.DateTime.Now.Millisecond);
                Trace.WriteLine((x++).ToString());
                tmrShowData.Enabled = true;
            }
      

  17.   

    如果你的执行时间超过了Timer的间隔时间,而且这可能一直累积下去,我建议你不要设置那么短的间隔,不然你的CPU会一直100%运行中,程序本身甚至会无响应的。所以是否超过了Timer设置的间隔,看CPU使用率基本可以看得出来。
      

  18.   

    Timer都是异步计时,不过你可以设置Timer一次执行当中停止计时,调用“Timer.Stop();”把它停了,处理好任务后再调用“Timer.Start()”把它开启。当然要这么做的话,似乎使用System.Threading.Timer类操作好些,但是要注意System.Threading.Timer的事件触发执行也是异步的,而System.Windows.Forms.Timer的事件触发执行是已经调用过了委托的,是同步执行的。
      

  19.   

    出两次是不是双核的原因? 
    我为了不重入就加了 lock代码,但是出来了两次,是不是双核的原因。
      

  20.   

    我发现输出变乱的问题了,是trace的问题。不知道c#的trace是怎么回事。 c#的winform中的timer和c++的timer是一样的哦?
      

  21.   

    难道TRACE就是两份,真的好奇怪
      

  22.   

    不可能吧......
    我用楼主的代码,测试结果是:
    1.32:609
    2.34:625
    0
    1.34:625
    2.36:625
    1
    1.36:625
    2.38:625
    2
    ....
    如果楼主真的用的是System.Windows.Forms.Timer,那么当前线程就是界面线程,Sleep了界面线程,消息循环当然也就停住了,System.Windows.Forms.Timer是用的消息循环,不可能有楼主这种输出。
    楼主这种输出很可能不是用的System.Windows.Forms.Timer。
      

  23.   

    对了,上面我把Sleep(200)改成Sleep(2000)了System.Windows.Forms.Timer的Tick是不会另起线程的,它是基于windows消息机制。
      

  24.   

    与双核当然没关系。
    从现象看,你的Timer事件是多个线程在执行,但System.Windows.Forms里的Timer是不会启动多线程的。
      

  25.   

    楼主方便的话把你的代码给我发一遍[email protected]
      

  26.   

    这里  Thread.Sleep(200); 没把法把定时期休眠,只不过这个tmrShowData_Tick执行的时候休眠0.2秒 
      tmrShowData_Tick还是按照100的间隔继续执行