public void Pulse_ReleasesOneWaiter() { AsyncContext.Run(async () => { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = new TaskCompletionSource(); var task2Ready = new TaskCompletionSource(); Task<IDisposable> lockTask1 = null; Task waitTask1 = null; var task1 = Task.Run(async () => { lockTask1 = monitor.EnterAsync(); using (await lockTask1) { waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; Task<IDisposable> lockTask2 = null; Task waitTask2 = null; var task2 = Task.Run(async () => { lockTask2 = monitor.EnterAsync(); using (await lockTask2) { waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; Task<IDisposable> lockTask3 = monitor.EnterAsync(); using (await lockTask3) { monitor.Pulse(); } await Task.WhenAny(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.AreEqual(1, result); }); }
public async Task WillPulseMonitor() { var monitor = new AsyncMonitor(); var sw = Stopwatch.StartNew(); // Monitor will not be pulsed and should be cancelled after 100ms. using (await monitor.EnterAsync()) await Assert.ThrowsAsync<TaskCanceledException>(async () => await monitor.WaitAsync(TimeSpan.FromMilliseconds(100).ToCancellationToken())); sw.Stop(); Assert.InRange(sw.ElapsedMilliseconds, 75, 125); var t = Task.Run(async () => { await Task.Delay(25); using (await monitor.EnterAsync()) monitor.Pulse(); }); sw = Stopwatch.StartNew(); using (await monitor.EnterAsync()) await monitor.WaitAsync(TimeSpan.FromSeconds(1).ToCancellationToken()); sw.Stop(); Assert.InRange(sw.ElapsedMilliseconds, 25, 100); }
public void Pulse_ReleasesOneWaiter() { Test.Async(async () => { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = new TaskCompletionSource(); var task2Ready = new TaskCompletionSource(); var task1 = TaskShim.Run(async () => { using (await monitor.EnterAsync()) { var waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; var task2 = TaskShim.Run(async () => { using (await monitor.EnterAsync()) { var waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; using (await monitor.EnterAsync()) { monitor.Pulse(); } await TaskShim.WhenAny(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.AreEqual(1, result); }); }