none
关于c#定时器的问题 RRS feed

  • 问题

  • 在.net内部有三个Timer,我现在需要一个30ms的精确定时,但这三个Timer的精度达不到要求,现在实验的结果是30ms的定时实际为31.8ms。
    请问各位老师有什么好的实现方法么?

    北辰之神,苍青之君,广兮长空,以翱以翔
    2009年7月24日 1:14

答案

全部回复

  • 你好,Timer不能用于精确定时,如果时间要求精确建议使用Thread!
    jon.valett@gmail.com
    2009年7月24日 1:53
    版主
  • Timer我已经放弃了,那么应该如何使用Thread呢?我试了下,依然不准,而且不稳定。是不是我下面的代码哪里错了


    Int64 t1 = 0;
    Stopwatch stopWatch = new Stopwatch();
    Thread Timer = new Thread(new ParameterizedThreadStart(MyTimer));
                Timer.Start();


     void MyTimer(object obj)
            {
                stopWatch.Start();
                t1 = stopWatch.ElapsedMilliseconds;
                while (true)
                {
                    if (stopWatch.ElapsedMilliseconds - t1 > 30)
                    {
                        t1 = stopWatch.ElapsedMilliseconds;
                        TimerElapsed();//要处理的代码段
                    } 
                }
            }
    北辰之神,苍青之君,广兮长空,以翱以翔
    2009年7月24日 2:03
  • 毫秒级别确实有点难,可以用循环来做,用 System.Threading.Thread.Sleep(32),但不是百分之百准确,也存在着误差。
            public static void Main()
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(FF));
                 Thread.Sleep(1000);
            }
            static void FF(Object stateInfo)
            {          
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(32);
                    Console.WriteLine(DateTime.Now.Millisecond);
                }
            }


    山西.net俱乐部
    2009年7月24日 2:05
    版主
  • 楼主,您好,Windows不是实时操作系统,每个线程cpu时间的分配都会被调度安排,应该达不到您的精确要求。
    2009年7月24日 3:02
  • 的确啊!Windows不是实时的操作系统,很难实现你的要求!
    周雪峰
    2009年7月24日 4:01
    版主
  • threading.timer 应该很准阿   你是怎么调用的
    答案900, 目标五颗星 Aurvana Air, 音乐真的是随风飘来的 凉宫春日 永无止境的八月 你到底什么时候结束阿。。。。
    2009年7月24日 4:19
    版主
  • 不管怎样,是做不到精确定时的,就像float类型一样,总是近似值。因为受计算机结构所限,你真要追求“极”精确的话,用工控机还差不多。
    http://hi.baidu.com/2009ajun
    2009年7月24日 4:25
  • 贴一下下午的代码:

    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    TimerCallback s=new TimerCallback (TimerElapsed );
                System.Threading.Timer Timer = new System.Threading.Timer(s, null, 200, 30);

     void TimerElapsed(object obj)
            {
                if (_intPollingTime % 6 == 0)//全轮询
                {
                    _IsAllPolling = true;
                    if (_intPDAIndexNow == 0)
                    {
                        PDA_ListSurvive.Clear();
                    }
                    SendData(PDA_ListAll[_intPDAIndexNow].Message);
                    Console.WriteLine(stopWatch.ElapsedMilliseconds.ToString());//测试用
                    _intPDAIndexNow++;
                    if (_intPDAIndexNow == PDA_ListAll.Count)
                    {
                        _intPDAIndexNow = 0;
                        _intPollingTime++;
                    }
                }
                else//存活轮询
                {
                    _IsAllPolling = false;
                    if (PDA_ListSurvive.Count != 0)
                    {
                        SendData(PDA_ListSurvive[_intPDAIndexNow].Message);
                        _intPDAIndexNow++;

                        if (_intPDAIndexNow == PDA_ListSurvive.Count)
                        {
                            _intPDAIndexNow = 0;
                            _intPollingTime++;
                        }
                    }
                    else
                    {
                        Console.WriteLine(stopWatch.ElapsedMilliseconds.ToString());
                        _intPDAIndexNow = 0;
                        _intPollingTime++;
                    }
                    if (_intPollingTime == 6)
                    {
                        //这里加一个广播
                        _intPollingTime = 0;
                    }
                }
            }

    用Console监视的结果是
    202
    231
    262
    292
    322
    352
    383
    413
    443
    474
    504
    549
    579
    609
    640
    670
    700
    730
    761
    791
    821
    852
    882
    912
    942
    973
    1018
    基本上可以达到30ms的要求了,但是每隔固定时间,会出现一次间隔为45ms。

    另外我也知道windows做这点很难,但老板不懂软件,逼着我实现这个。。。哭啊。。。


    北辰之神,苍青之君,广兮长空,以翱以翔
    2009年7月24日 7:42
  • 您好,在任务管理器中将进程优先级设置为“实时”。
    还不行,可以在发布时,单独用一台电脑来跑,关闭所有不用的服务和程序,给Windows瘦身。

    • 已编辑 Jiyuan 2009年7月24日 9:25
    2009年7月24日 9:21
  • 我这还只是开了一个站,设计需求是最多8个站。。。要是全跑起来真不知道会成什么样子
    北辰之神,苍青之君,广兮长空,以翱以翔
    2009年7月24日 9:23
  • 在任务管理器中将进程优先级设置为“实时”试试。
    2009年7月24日 9:30