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

c00*_*0fd 7 .net c# windows synchronization timer

在非托管的Win32世界中,我习惯使用CreateWaitableTimer API 创建的等待计时器,可以用于WaitForSingleObject等同步调用,主要用于WaitForMultipleObjects.

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

Dan*_*iel 6

你需要什么等待计时器?

.NET中"我可以等待的东西"的默认类是System.Threading.Tasks.Task.在.NET 4.5中,您可以简单地使用Task.Delay(milliseconds).

在.NET 4.0中,您可以使用a TaskCompletionSource创建任务,并使用普通计时器将其设置为已完成.或者使用TaskEx.Delay从实现异步定位包AsyncBridge

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

或者,您可以创建自己的派生自WaitHandleP/Invoke的类CreateWaitableTimer.似乎这样的类已经存在于.NET框架中,但它是内部的.(System.Runtime.IOThreadTimer.WaitableTimer来自System.ServiceModel.Internals.dll)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我需要它包含在等待函数中(它将等待多个对象:事件,其中一个是计时器。)我知道我可以使用回调函数来完成此操作,但这需要重新设计我的代码。所以,是的,看来我必须使用 Win32 API 和 P/Invoke。我只是不太擅长做 P/Invoke 的事情...这是我找到的链接:http://www.anotherchris.net/csharp/wake-up-from-sleep-createwaitabletimer-in-csharp/ (2认同)
  • “你需要等待计时器做什么?” 答案可能包括在绝对时间(而非相对时间)唤醒的能力,包括考虑系统时钟的变化,以及在发生超时时根据需要从挂起状态恢复计算机。 (2认同)