Per cosa serve il timer?
La classe predefinita per "qualcosa che posso aspettare" in .NET è System.Threading.Tasks.Task
. In .NET 4.5, puoi semplicemente usare Task.Delay(milliseconds)
.
In .NET 4.0, è possibile utilizzare un TaskCompletionSource
per creare un'attività e impostarlo come completato utilizzando un normale timer. Oppure utilizzare il TaskEx.Delay
implementazione della Async Targeting Pack o AsyncBridge
Se avete bisogno di un vero e proprio WaitHandle
, è possibile utilizzare un ManualResetEvent
, e utilizzare un normale timer NET per impostare l'evento.
In alternativa, è possibile creare la propria classe derivata da WaitHandle
e P/Invoke CreateWaitableTimer
. Sembra che tale classe esista già nel framework .NET, ma è interna. (System.Runtime.IOThreadTimer.WaitableTimer
da 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();
}
}
}
ho bisogno di includere in una funzione di attesa (che attende la più oggetti:. Eventi e uno di loro è un timer) ho capito che posso fare questo con una funzione di callback, ma ciò richiederebbe una riprogettazione del mio codice. Quindi, sì, sembra che dovrò andare con Win32 API e P/Invoke. Non sono molto bravo a fare questa roba P/Invoke ... Ecco il link che ho trovato: http://www.anotherchris.net/csharp/wake-up-from-sleep-createwaitabletimer-in-csharp/ – c00000fd
Quel collegamento mi sembra buono; tranne che userei una classe personalizzata 'WaitHandle' invece di' EventWaitHandle'. Il codice nel collegamento finisce per creare un 'AutoResetEvent' inutilizzato. – Daniel
Grazie. Un problema che ho riscontrato è che se creo un timer ripetuto (o quando il terzo parametro di 'SetWaitableTimer' non è 0), chiamando il primo' wh.WaitOne() 'funziona, ma se lo chiamo di nuovo, non lo fa t attendere il periodo del timer. Qualche idea del perché? – c00000fd