类似于.NET中的等待计时器

时间:2013-04-07 04:06:15

标签: c# .net windows timer synchronization

在非托管的Win32环境中,我习惯于使用CreateWaitableTimer API创建的等待计时器,可用于同步调用,例如WaitForSingleObject,主要用于WaitForMultipleObjects

在.NET和C#中必须有一个模拟可等待的计时器?

1 个答案:

答案 0 :(得分:6)

你需要什么样的等待计时器?

我可以等待'的默认课程。在.NET中是System.Threading.Tasks.Task。在.NET 4.5中,您只需使用Task.Delay(milliseconds)

在.NET 4.0中,您可以使用TaskCompletionSource创建任务,并使用普通计时器将其设置为已完成。或者使用Async Targeting PackAsyncBridge

中的TaskEx.Delay实施

如果您需要实际WaitHandle,可以使用ManualResetEvent,并使用普通的.NET计时器来设置事件。

或者,您可以创建自己的类,该类派生自WaitHandle和P / Invoke CreateWaitableTimer。 似乎这样的类已经存在于.NET框架中,但它是内部的。 (来自System.ServiceModel.Internals.dll的{​​{3}})

public class WaitableTimer : WaitHandle
{
    [DllImport("kernel32.dll")]
    static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, [MarshalAs(UnmanagedType.Bool)] bool fResume);

    public WaitableTimer(bool manualReset = true, string timerName = null)
    {
        this.SafeWaitHandle = CreateWaitableTimer(IntPtr.Zero, manualReset, timerName);
    }

    public void Set(long dueTime)
    {
        if (!SetWaitableTimer(this.SafeWaitHandle, ref dueTime, 0, IntPtr.Zero, IntPtr.Zero, false))
        {
            throw new Win32Exception();
        }
    }
}