在非託管Win32世界中,我習慣於使用CreateWaitableTimer API創建的等待計時器可用於同步呼叫,例如WaitForSingleObject,主要用於WaitForMultipleObjects。類似於.NET中的等待計時器
在.NET和C#中必須有一個等待計時器的類比嗎?
在非託管Win32世界中,我習慣於使用CreateWaitableTimer API創建的等待計時器可用於同步呼叫,例如WaitForSingleObject,主要用於WaitForMultipleObjects。類似於.NET中的等待計時器
在.NET和C#中必須有一個等待計時器的類比嗎?
你需要什麼等待定時器?
.NET中'我可以等待'的默認類是System.Threading.Tasks.Task
。在.NET 4.5中,您可以簡單地使用Task.Delay(milliseconds)
。
在.NET 4.0中,您可以使用TaskCompletionSource
創建任務,並使用普通定時器將其設置爲完成。或者使用從Async Targeting Pack或AsyncBridge
的TaskEx.Delay
實現如果你需要一個實際的WaitHandle
,你可以使用一個ManualResetEvent
,並使用普通的.NET計時器設置事件。
或者,您可以創建自己的類,從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();
}
}
}
我需要它在等待功能包括(即等待多個對象:事件,其中一人是一個定時器),我知道我可以用一個回調函數做到這一點,但那需要重新設計我的代碼。所以,是的,看起來我必須使用Win32 API和P/Invoke。我只是不太擅長做這個P/Invoke的東西......這裏是我找到的鏈接:http://www.anotherchris.net/csharp/wake-up-from-sleep-createwaitabletimer-in-csharp/ – c00000fd 2013-04-07 05:09:59
那條鏈接對我來說很好;除了我會使用自定義的'WaitHandle'派生類而不是'EventWaitHandle'。鏈接中的代碼最終創建了一個未使用的'AutoResetEvent'。 – Daniel 2013-04-07 05:40:30
謝謝。我遇到的一個問題是,如果我創建一個重複定時器(或者當SetWaitableTimer的第三個參數不是0),調用第一個'wh.WaitOne()'就行,但如果我再次調用它,它不會'等待計時器的時間。任何想法爲什麼? – c00000fd 2013-04-07 06:55:56