How can I use CreateTimerQueueTimer to create a high resolution timer in C#?

后端 未结 3 1942
青春惊慌失措
青春惊慌失措 2021-01-18 05:54

I\'ve used a Windows multimedia dll to created a high resolution timer with

timSetEvent()

But the timeSetEvent() page recommends the use

3条回答
  •  温柔的废话
    2021-01-18 06:07

    The callback passed to CreateTimerQueueTimer is expected to be an unmanaged function which will exist for the lifetime of the callbacks. The managed delegate can move about in memory but the underlying stub created by the marshalling will not do this so there is no need to pin the delegate. There is however a need to keep the delegate from being garbage collected since the pointer from unmanaged code is not sufficient to keep it alive. You must therefore ensure that either the delegate is kept alive by some managed reference being maintained (Perhaps through the use of GCHandle

    The PVOID Parameter which is passed to the callback function must be fixed in memory since again, the unmanaged function expects it not to move about after the function returns. In .Net this pinning happens (efficiently) automatically but only for the life of the called function. Thus if you are using a reference to some managed object (say by getting an IntPtr to it) the underlying object must be pinned (again the GCHandle can be used for that in a subtly different way). To see if this is the problem try using IntPtr.Zero as the parameter to test if it works.

    If this solves things you will need to either allocate your parameter as raw bytes in the unmanaged heap (and marshal accordingly), use some blittable type that is safe to put into something of size PVOID (like an Int32) or use the GCHandle technique above to maintain a stable pointer to a managed instance, this will have significant performance implications if done wrongly.

提交回复
热议问题