如何使用CreateTimerQueueTimer建立在C#中高分辨率计时器?(How can I

2019-06-23 15:29发布

我用一个Windows多媒体DLL创建高分辨率定时器

timSetEvent()

但是timeSetEvent()页建议使用:

CreateTimerQueueTimer()

如何使用CreateTimerQueueTimer()来执行每10毫秒在C#中的方法?

Answer 1:

这里是一个C#包装中的链接CreateTimerQueueTimer

http://social.msdn.microsoft.com/Forums/en-CA/csharpgeneral/thread/822aed2d-dca0-4a8e-8130-20fab69557d2

(下降滚动到最后一个职位Hobz为样本类)

我只是想这一点,我和它工作正常。 有一件事你需要添加,虽然是一个呼叫timeBeginPeriod(1)为了您的系统设置为高分辨率启动定时器之前。 timeSetEvent调用timeBeginPeriod内部,这就是为什么有些人误以为它创建了一个更高分辨率的定时器。



Answer 2:

传递给CreateTimerQueueTimer回调预计将在回调的生命周期中存在的非托管函数。 该管理委托可以在内存中移动有关,但在编组创建将无法做到这一点的基础存根,所以没有必要针委托 。 然而,有必要保持委托被垃圾收集因为从非托管代码的指针并不足以让它活着。 因此,你必须确保两个委托是由一些管理参考更让维持(也许通过使用的GCHandle

这是传递给回调函数的参数PVOID必须固定内存,因为再次,非托管函数希望它不要在函数返回之后走​​动。 在.net中,此钉扎发生(有效)自动但只被调用函数的使用寿命。 因此,如果你正在使用(通过获取一个IntPtr说这句话)基础对象的一些管理对象的引用,必须固定(再次的GCHandle可以在一个微妙的不同的方式使用该)。 要看到,如果这是问题尝试使用IntPtr.Zero作为参数,以测试它是否工作。

如果这样可以解决的事情,你要么需要分配您的参数作为非托管堆中(相应元帅)原始字节,使用一些blittable类型,它是安全的投入规模PVOID(如一个Int32)的东西,或者使用上述的GCHandle技术保持稳定的指针管理例如,如果错误地做这将有显著的性能影响。



Answer 3:

这是更好地使用,因为的timeSetEvent其结果是比较一致的。 平均而言,现代化的硬件,对于小的时间间隔,在间隔的长度偏差使用CreateTimerQueueTimer时小于约十倍。 这就是假设你没有忘记呼吁CreateTimerQueueTimer之前增加计时器的分辨率,否则差异将更大。 因此,使用替代的timeSetEvent。



文章来源: How can I use CreateTimerQueueTimer to create a high resolution timer in C#?
标签: c# timer