2013-04-07 21 views

回答

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.Runtime.IOThreadTimer.WaitableTimerSystem.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(); 
     } 
    } 
} 
+1

我需要它在等待功能包括(即等待多個對象:事件,其中一人是一個定時器),我知道我可以用一個回調函數做到這一點,但那需要重新設計我的代碼。所以,是的,看起來我必須使用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

+1

那條鏈接對我來說很好;除了我會使用自定義的'WaitHandle'派生類而不是'EventWaitHandle'。鏈接中的代碼最終創建了一個未使用的'AutoResetEvent'。 – Daniel 2013-04-07 05:40:30

+0

謝謝。我遇到的一個問題是,如果我創建一個重複定時器(或者當SetWaitableTimer的第三個參數不是0),調用第一個'wh.WaitOne()'就行,但如果我再次調用它,它不會'等待計時器的時間。任何想法爲什麼? – c00000fd 2013-04-07 06:55:56