7

管理されていない Win32 の世界では、CreateWaitableTimer API で作成された待機可能なタイマーに慣れています。これは、 WaitForSingleObjectなどの同期呼び出しや、主にWaitForMultipleObjectsに使用できます。

.NET と C# には、待機可能なタイマーに類似したものが必要ですか?

4

1 に答える 1

6

待機可能なタイマーは何のために必要ですか?

.NET での「待機できるもの」のデフォルト クラスはSystem.Threading.Tasks.Task. .NET 4.5 では、単純にTask.Delay(milliseconds).

.NET 4.0 では、 を使用しTaskCompletionSourceてタスクを作成し、通常のタイマーを使用して完了として設定できます。またはTaskEx.DelayAsync Targeting PackまたはAsyncBridgeの実​​装を使用します

実際の が必要な場合は、 を使用し、通常の .NET タイマーを使用してイベントを設定WaitHandleできます。ManualResetEvent

WaitHandleまたは、 P/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();
        }
    }
}
于 2013-04-07T04:47:00.527 に答える