Sya*_*hya 15 c# timer stopwatch
我想使用c#使用最高分辨率计时器.例如,我想每11个刻度提升一个事件(我听说刻度是pc中最高的计数器).我试过计时器,发现最小经过时间以毫秒为单位.我看了秒表,但秒表不会引发事件.
谢谢.
Cod*_*eld 18
使用多媒体计时器应该每秒给你大约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 );
Run Code Online (Sandbox Code Playgroud)
运行它们后,请停止这些计时器.它们对你的系统非常沉重*.捕获所有异常并且不要让它们逃脱您的事件处理程序.
*启动超过5个计时器将严重减慢大多数系统!在事件处理程序中执行尽可能少的代码,并确保执行代码快于1毫秒或遇到严重问题.我每隔10-50滴就开始一个代表,以增加标签显示.
在a上发生的正常线程切换Thread.Sleep将使一个线程槽无需代码,并且将花费大约40毫秒.您也可以通过一些NT内核调用来增加线程切换频率,但请不要这样做.
Cod*_*ray 14
首先,你需要意识到,由于硬件和软件都有限制,在计算机上进行精确计时是非常困难的,如果不是不可能的话.好消息是这种精度很少是必要的.十蜱是一个非常少的时间.在这个时间间隔内,CPU完成的工作很少,而且从来没有统计意义.
作为参考,Windows时钟的精度约为10毫秒(早期版本较少).通过调用来包装代码DateTime.UtcNow不会比这更好.
在你的问题中,你谈到想要"举办活动".问题是,以特定间隔引发事件的唯一类型的计时对象是Timer对象.它在.NET Framework(System.Timers.Timer,System.Threading.Timer和System.Windows.Forms.Timer)中提供了3种不同的版本,所有这些都有自己独特的使用场景和相对怪癖,但它们都不能保证精确到任何接近你要求的地方.它们甚至不是为此而设计的,并且Windows API也没有提供任何能够提供此类精度的等效函数.
我之所以问你为什么要这样做以及你是否想要进行基准测试的原因是因为这会改变整个游戏..NET Framework(从2.0版开始)提供了一个Stopwatch对象,该对象专门用于准确测量基准测试或性能分析等情况所用的时间.在Stopwatch简单地封装了Windows API函数QueryPerformanceFrequency和QueryPerformanceCounter(应确认我的建议,以达到预定可使用).我们过去必须使用P/Invoke这些函数来在早期版本的Framework中访问这种类型的功能,但它现在已经方便地内置了.如果你需要一个具有相对较高分辨率的计时器进行基准测试,那么这Stopwatch是你最好的选择.从理论上讲,它可以为您提供亚微秒的时序.
但它并非没有问题.它不会引发任何事件,因此如果您当前的设计依赖于事件处理,那么您将不得不重新考虑它.并且,它也不能保证完全准确.当然,考虑到硬件限制,它可能具有尽可能高的分辨率,但这并不意味着它必然符合您的规定要求.例如,在多处理器系统上它可能是不可靠的,其中Start并且Stop必须在同一处理器上执行.它应该没关系,但确实如此.它也可能在处理器上不可靠,可以上下调节时钟速度.我甚至敢提到这个号召QueryPerformanceCounter它本身需要一些时间 - 大约5微秒,即使在现代的2+ GHz处理器上,这也会阻止你实际上能够实现理论上听起来不错的亚微秒时序.然后,任何合理的代码分析器都会认为这段时间可以忽略不计,因为它确实存在.
(另见:http://www.devsource.com/c/a/Techniques/High-Performance-Timing-under-Windows/2/)