public async Task RechargeableCompletionSourceBlocksSetAwaitAfter(bool runContinuationsAsynchronously) { // Arrange var rcs = new RechargeableCompletionSource <object>(runContinuationsAsynchronously); var tFinishCheck = new TaskCompletionSource(); // Act var t = Task.Run(() => rcs.SetResultAndWait(null !)); _ = t.ContinueWith(_ => tFinishCheck.SetResult(), TaskContinuationOptions.ExecuteSynchronously); await Task.Delay(1_000); // Attempts to ensure that task t never completes. // Assert t.IsCompleted.Should().BeFalse(); var result = await rcs.GetValueAsync(); t.IsCompleted.Should().BeFalse(); result.Dispose(); await tFinishCheck.Task; t.IsCompleted.Should().BeTrue(); }
static async Task RechargeableCompletionSourceExampleAsync() { var runContinuationsAsynchronously = false; var rtcs = new RechargeableCompletionSource <int>(runContinuationsAsynchronously); var t1 = Task.Run(async() => { while (true) { using var data = await rtcs.GetValueAsync().ConfigureAwait(false); Console.WriteLine($"Get {data.Value} on Thread {Environment.CurrentManagedThreadId}"); } }); Thread.Sleep(1000); var t2 = Task.Run(() => { int i = 0; while (true) { Thread.Sleep(1_000); Console.WriteLine($"Add {i} on Thread {Environment.CurrentManagedThreadId}"); rtcs.SetResultAndWait(i++); } }); await Task.WhenAll(t1, t2).ConfigureAwait(false); }
public void RechargeableCompletionSourceThrowsErrorOnGetValueAsync(bool runContinuationsAsynchronously) { // Arrange var rcs = new RechargeableCompletionSource <object>(runContinuationsAsynchronously); // Act var t1 = rcs.GetValueAsync(); var t2 = rcs.GetValueAsync(); // Assert t1.IsFaulted.Should().BeFalse(); t2.IsFaulted.Should().BeTrue(); }