2013-04-07 14 views

Odpowiedz

6

Do czego potrzebny jest czas oczekiwania?

Domyślna klasa dla "czegoś, na co mogę czekać" w .NET to System.Threading.Tasks.Task. W .NET 4.5 możesz po prostu użyć Task.Delay(milliseconds).

W .NET 4.0 można użyć TaskCompletionSource, aby utworzyć zadanie i ustawić je jako zakończone przy użyciu zwykłego zegara. Lub użyj realizację TaskEx.Delay z Async Targeting Pack lub AsyncBridge

Jeśli potrzebujesz rzeczywistego WaitHandle, można użyć ManualResetEvent i użyć zwykłego .NET timer ustawiony zdarzenia.

Można również utworzyć własną klasę pochodną od WaitHandle i P/Invoke CreateWaitableTimer. Wygląda na to, że taka klasa istnieje już w środowisku .NET, ale jest wewnętrzna. (System.Runtime.IOThreadTimer.WaitableTimer z 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(); 
     } 
    } 
} 
+1

muszę go umieścić w funkcji oczekiwania (które będą czekać na wielu obiektach. Imprezy i jeden z nich jest timer) Rozumiem, że mogę to zrobić za pomocą funkcji wywołania zwrotnego, ale wymagałoby to przeprojektowania mojego kodu. Tak, tak, wydaje się, że będę musiał iść z Win32 API i P/Invoke. Po prostu nie jestem dobry w robieniu tego materiału P/Invoke ... Oto link, który znalazłem: http://www.anotherchris.net/csharp/wake-up-from-sleep-createwaitabletimer-in-csharp/ – c00000fd

+1

Ten link wygląda mi dobrze; z tą różnicą, że użyłbym niestandardowej klasy pochodnej 'WaitHandle' zamiast' EventWaitHandle'. Kod w łączu kończy się tworzeniem nieużywanego 'AutoResetEvent'. – Daniel

+0

Dzięki. Jedną z kwestii, której doświadczyłem, jest to, że jeśli utworzę powtarzający się timer (lub gdy trzeci parametr 'SetWaitableTimer' nie jest równy 0), wywołanie pierwszego' wh.WaitOne() 'działa, ale jeśli zadzwonię ponownie, to doesn ' t czekaj na czas licznika. Każdy pomysł, dlaczego? – c00000fd