Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Analog to waitable timers in .NET

In unmanaged Win32 world I am used to waitable timers created with the CreateWaitableTimer API that can be used for synchronization calls such as WaitForSingleObject and mainly for WaitForMultipleObjects.

There must be an analog to waitable timers in .NET and C#?

like image 419
c00000fd Avatar asked Apr 07 '13 04:04

c00000fd


1 Answers

What do you need the waitable timer for?

The default class for 'something I can wait for' in .NET is System.Threading.Tasks.Task. In .NET 4.5, you can simply use Task.Delay(milliseconds).

In .NET 4.0, you can use a TaskCompletionSource to create a task, and set it as completed using a normal timer. Or use the TaskEx.Delay implementation from the Async Targeting Pack or AsyncBridge

If you need an actual WaitHandle, you could use a ManualResetEvent, and use a normal .NET timer to set the event.

Alternatively, you chould create your own class derived from WaitHandle and P/Invoke CreateWaitableTimer. It seems that such a class already exists in the .NET framework, but it is internal. (System.Runtime.IOThreadTimer.WaitableTimer from 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();
        }
    }
}
like image 183
Daniel Avatar answered Oct 06 '22 18:10

Daniel