谢谢。
使用多媒体定时器应该能够每秒提供大约1000个事件。这段代码应该会对您有所帮助。
public delegate void TimerEventHandler(UInt32 id, UInt32 msg, ref UInt32 userCtx, UInt32 rsv1, UInt32 rsv2);
/// <summary>
/// A multi media timer with millisecond precision
/// </summary>
/// <param name="msDelay">One event every msDelay milliseconds</param>
/// <param name="msResolution">Timer precision indication (lower value is more precise but resource unfriendly)</param>
/// <param name="handler">delegate to start</param>
/// <param name="userCtx">callBack data </param>
/// <param name="eventType">one event or multiple events</param>
/// <remarks>Dont forget to call timeKillEvent!</remarks>
/// <returns>0 on failure or any other value as a timer id to use for timeKillEvent</returns>
[DllImport("winmm.dll", SetLastError = true,EntryPoint="timeSetEvent")]
static extern UInt32 timeSetEvent(UInt32 msDelay, UInt32 msResolution, TimerEventHandler handler, ref UInt32 userCtx, UInt32 eventType);
/// <summary>
/// The multi media timer stop function
/// </summary>
/// <param name="uTimerID">timer id from timeSetEvent</param>
/// <remarks>This function stops the timer</remarks>
[DllImport("winmm.dll", SetLastError = true)]
static extern void timeKillEvent( UInt32 uTimerID );
运行完计时器后,请停止它们。它们对系统负担很重。请捕获所有异常并确保它们不会逃离您的事件处理程序。
*启动超过5个计时器会严重拖慢大多数系统!在事件处理程序中尽可能执行较少的代码,并确保执行的代码快于1毫秒,否则将面临严重问题。我每10-50次滴答声启动了一个委托以增加标签显示。
Thread.Sleep
上发生的普通线程切换将使得您的代码有一个线程槽位空闲,并且大约需要40毫秒。您也可以通过一些NT内核调用来增加线程切换频率,但请不要这样做。
首先,你需要明白由于硬件和软件的限制,在计算机上做精确的定时几乎是不可能的,甚至非常困难。好消息是,这种精度很少是必须的。十个滴答声是一个非常短暂的时间间隔,CPU在这段时间内完成的工作非常少,而且从统计学的角度来看,它永远不会有意义。
作为参考,Windows时钟的精度约为10毫秒(早期版本则更低)。用DateTime.UtcNow
调用包装你的代码并不能达到比这更好的效果。
在你的问题中,你谈到想要“引发事件”。问题在于,唯一一种在特定时间间隔内引发事件的时间记录对象是Timer
对象。它在.NET Framework中有三种不同的实现方式(System.Timers.Timer
、System.Threading.Timer
和System.Windows.Forms.Timer
),它们都有自己独特的用途场景和相对应的怪癖,但它们都无法保证你所要求的精度。它们甚至没有被设计为这样做,也没有任何等效的Windows API函数能够提供这种类型的精度。
Stopwatch
对象。 Stopwatch
简单地包装了 Windows API 函数 QueryPerformanceFrequency
和 QueryPerformanceCounter
(这应该证实了我的建议)。 在 Framework 的早期版本中,我们曾经不得不 P/Invoke 这些函数才能访问此类功能,但现在已方便地内置在其中。 如果您需要具有相对较高分辨率的计时器进行基准测试,则 Stopwatch
是您的最佳选择。 理论上,它可以提供亚微秒级的计时。但是它也存在问题。它不会引发任何事件,因此如果您当前的设计依赖于事件处理,您需要重新考虑。而且,它也不能保证完全准确。 当然,鉴于硬件限制,它可能具有最高分辨率,但这并不意味着它一定能满足您的要求。例如,在多处理器系统上,必须在同一个处理器上执行Start
和Stop
时,它可能不可靠。这应该无关紧要,但实际上却很重要。它还可能不可靠,因为处理器可以调节其时钟速度。更何况,即使在现代的2+ GHz处理器上,调用QueryPerformanceCounter
本身也需要大约5微秒的时间,这导致您实际上无法达到理论上听起来很好的亚微秒级定时。不过,任何合理的代码分析器都会认为这个时间量是可以忽略的,因为,嗯,它确实可以被忽略。
(另请参见:http://www.devsource.com/c/a/Techniques/High-Performance-Timing-under-Windows/2/)
stopwatch.frequency
类型的计时。换句话说,就是处理器周期计时。 - Syaiful Nizam Yahyawhile(true) { ... }
。 - David Yaw