C# 系统计时器计时器类执行,精度测试

C# 系统计时器计时器类执行,精度测试,c#,timer,C#,Timer,我编写了这段简单的代码,但结果不合理: public MainWindow() { InitializeComponent(); write w = new write(); } public class write{ Timer timer = new Timer(100); public write() { timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } St

我编写了这段简单的代码,但结果不合理:

public MainWindow()
{
    InitializeComponent();
    write w = new write();
}
public class write{
Timer timer = new Timer(100);

public write()
{
    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    timer.Start();
}
StreamWriter str = new StreamWriter("write.txt");
int index = 0;
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    index++;
    if (index>100)
    {
        timer.Stop();
        str.Close();
        return;
    }
    for (int i = 0; i < 1000; i++)
    {
        //do something
        //run simple commands
    }
    str.WriteLine(DateTime.Now.Millisecond.ToString());
}
public主窗口()
{
初始化组件();
write w=新的write();
}
公共类写作{
定时器=新定时器(100);
公开写作()
{
timer.appeased+=新的ElapsedEventHandler(timer\u appeased);
timer.Start();
}
StreamWriter str=新的StreamWriter(“write.txt”);
int指数=0;
无效计时器已过(对象发送器,ElapsedEventArgs e)
{
索引++;
如果(索引>100)
{
timer.Stop();
str.Close();
返回;
}
对于(int i=0;i<1000;i++)
{
//做点什么
//运行简单的命令
}
str.WriteLine(DateTime.Now.millis秒.ToString());
}
结果是:

263
365
479
585
697
803
917
24
132
242
348
462
569
675
787
899
6.
113
225
331
443
550
664
770
876
988
95
209
315
427
533
647
754
860
972
78
192
299
405
517
629
736
843
955
61
173
280
394
500
606
718
825
939
45
157
263
377
484
590
702
808
922
29
135
247
353
467
574
686
792
904
11
118
230
336
448
555
669
775
887
993
107
214
320
432
538
652
759
865
977
83
197
304
416
522
634
741
848
960
66


为什么它不能以100毫秒的步长执行?是否真的需要1000次迭代(没有任何命令)才能执行,写入文件的时间大约为12毫秒?(参见最后的结果)。

计时器类是出了名的不准确

秒表准确无误:


但不支持调度。如果您想要精确调度,您必须在CLR中查找不存在的内容或编写自己的内容。

简而言之:您观察到的平均步长时间约为109.15毫秒。更多样本可能会收敛到平均109.375毫秒。系统时间的粒度可能为15.6250毫秒(注意:这可能因硬件/软件平台而异)。系统时间进度的七个步骤累积到109.3750毫秒。这几乎说明您在15.6250毫秒心跳平台上运行

您可以通过更改系统计时行为来提高准确性。Windows允许您使用

编辑:更多详细信息:

以较小的中断周期运行将强制在Windows>XP SP3(5.1.3)上更频繁地更新系统时间。这会降低系统时间的粒度,从而降低
system.Timers.Timer
的粒度。请记住,这可能不适用于使用Windows XP操作的特定平台


您可能会获得1毫秒的精度。但是,无法保证,因为调度可能会将任务暂停一段未指定的时间。这只能通过提高进程/线程优先级来解决。有关优先级和修改优先级的详细信息,请参阅和。

您的精度测试没有意义或者是我。这取决于资源的可用性。这里没有什么不对的……如何改进它?我能获得大约5毫秒的准确度吗?@abdolah:通过一些编码工作,5毫秒甚至更少。请参阅我答案中的附加信息。
#define TARGET_PERIOD 1         
TIMECAPS tc;
UINT     wTimerRes;

if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) 
{
    // Error; application can't continue.
}
// Note: tc.wPeriodMin will be 1 for most platforms, however, the following
// line won't allow anything smaller than 1.

wTimerRes = min(max(tc.wPeriodMin, TARGET_PERIOD), tc.wPeriodMax);
// the smallest permitted period is assigned to wTimerRes.

timeBeginPeriod(wTimerRes); 
// most people just say timeBeginPeriod(1); but that's rude
// this call will set the systems interrupt period to the minimum possible.