请注意,我要问的是,使用类似的东西,每隔15毫秒就会调用一次回调函数System.Threading.Timer
.我不是在询问如何使用类似System.Diagnostics.Stopwatch
甚至是类似的东西准确计算代码QueryPerformanceCounter
.
另外,我已经阅读了相关问题:
准确的Windows计时器?System.Timers.Timer()限制为15毫秒
这些都没有为我的问题提供有用的答案.
此外,推荐的MSDN文章" 为Windows实现连续更新,高分辨率时间提供程序"是关于计时而不是提供连续的滴答流.
照这样说...
关于.NET计时器对象有很多不好的信息.例如,System.Timers.Timer
被称为"针对服务器应用程序优化的高性能计时器".并且System.Threading.Timer
在某种程度上被认为是二等公民.传统的观点认为,System.Threading.Timer
是围绕Windows的包装定时器队列定时器,并且System.Timers.Timer
完全是另一回事.
现实情况大不相同. System.Timers.Timer
只是一个瘦的组件包装器System.Threading.Timer
(只需使用Reflector或ILDASM来查看内部System.Timers.Timer
,你会看到引用System.Threading.Timer
),并有一些代码将提供自动线程同步,所以你不必这样做.
System.Threading.Timer
事实证明,它不是 Timer Queue Timers的包装器.至少不在2.0运行时,它是从.NET 2.0到.NET 3.5使用的.使用Shared Source CLI几分钟后,运行时会实现自己的定时器队列,类似于Timer Queue Timers,但实际上从不调用Win32函数.
似乎.NET 4.0运行时还实现了自己的计时器队列.我的测试程序(见下文)在.NET 4.0下提供与.NET 3.5相似的结果.我已经为Timer Queue Timers创建了自己的托管包装器并证明我可以获得1 ms的分辨率(具有相当好的准确性),所以我认为我不太可能错误地读取CLI源代码.
我有两个问题:
首先,是什么原因导致运行时计时器队列的实现如此缓慢?我的分辨率不能超过15毫秒,精度似乎在-1到+30毫秒的范围内.也就是说,如果我要求24毫秒,我会在23到54毫秒之间的任何地方得到滴答声.我想我可以花更多时间使用CLI源来追踪答案,但我想这里有人可能知道.
其次,我意识到这很难回答,为什么不使用定时器队列定时器?我意识到.NET 1.x必须在没有这些API的Win9x上运行,但它们自Windows 2000以来就存在,如果我没记错的话,那就是.NET 2.0的最低要求.是因为CLI必须在非Windows机器上运行吗?
我的计时器测试程序:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace TimerTest
{
class Program
{
const int TickFrequency = 5; …
Run Code Online (Sandbox Code Playgroud)