Use C#/VB await keyword with AutoResetEvent, ManualResetEvent, or Semaphore in .NET apps Extension methods for the WaitHandle class are available in the System.Threading namespace for your convenience. Available as NuGet package 'AsyncWaitHandle' on nuget.org: https://www.nuget.org/packages/AsyncWaitHandle/ Exammple 1 (simple await): var e = new AutoResetEvent(); ... await e; Exammple 2 (configured await): var e = new AutoResetEvent(); var cts = new CancellationTokenSource(); ... var timeout = TimeSpan.FromSeconds(30); try { await e.ConfigureAwait(timeout, cts.Token); } catch (TimeOutException) { ... } catch (OperationCanceledException) { ... } Exammple 3 (WaitOneAsync): var e = new AutoResetEvent(); var cts = new CancellationTokenSource(); ... var timeout = TimeSpan.FromSeconds(30); bool fSignaled; try { fSignaled = await e.WaitOneAsync(timeout, cts.Token); } catch (OperationCanceledException) { ... } Exammple 4 (WaitAnyAsync): var events = new WaitHandle[] { new AutoResetEvent(), new ManualResetEvent() }; var cts = new CancellationTokenSource(); ... var timeout = TimeSpan.FromSeconds(30); int signaledIndex; try { signaledIndex = await events.WaitAnyAsync(timeout, cts.Token); } catch (OperationCanceledException) { ... } switch (signaledIndex) { case 0: ... case 1: ... case WaitHandle.Wait... } Exammple 5 (WaitAllAsync): var events = new WaitHandle[] { new AutoResetEvent(), new ManualResetEvent() }; var cts = new CancellationTokenSource(); ... var timeout = TimeSpan.FromSeconds(30); bool allSignaled; try { allSignaled = await events.WaitAllAsync(timeout, cts.Token); } catch (OperationCanceledException) { ... }