static async Task Main(string[] args) { ExploreAsyncAwait.output = Output; Console.WriteLine("Which Exercise to run? (1 - )"); int result; while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out result)) { Console.WriteLine("Invalid Entry"); } switch (result) { case 1: // Exercise 1 - Baseline await ExploreAsyncAwait.AsyncAwait_A(); break; case 2: // Exercise 2 - Task Debugger Window await ExploreAsyncAwait.AsyncAwait_A(pause : 10000); break; case 3: // Exercise 3 - Don't await // Note the warning - Don't ignore these ExploreAsyncAwait.AsyncAwait_A(); break; case 4: // Exercise 4 - Don't await, exception lost ExploreAsyncAwait.ThrowException(); break; case 6: // Exercise 4 - .Wait() // Works ExploreAsyncAwait.AsyncAwait_A(pause: 5000).Wait(); break; case 0: break; default: Console.WriteLine("Incorrect"); Console.ReadKey(); break; } Console.WriteLine("Done"); Console.ReadKey(); }
public void AsyncAwaitExercise7_Click(object sender, RoutedEventArgs e) { Output("Exercise 7"); // Exercise 7 - .Wait() with ConfigureAwait(false) // Deadlock resolved the correct way using ConfigureAwait(false) // UI Thread Blocked // Note the log - Different thread completes the task (Logical Execution 7+) that the main thread is waiting for to complete alleviating the deadlock ExploreAsyncAwait.AsyncAwait_A(continueOnCapturedSynchronizationContext: false, pause: 5000) .Wait(); Messages.Add("Exercise 7 Done"); }
public async void AsyncAwaitExercise17_Click(object sender, RoutedEventArgs e) { // Exercise 17 // Note the values of AsyncLocal in the output window // This is because AsyncLocal is within a container within ExecutionContext // Execution.Run is part of back - end mechanics of asynchronous forks(await, Task.Run) // Not any real world value - Just bringing together the concepts // And driving home the fact that these are instances of object like any other // This is the type of work Async / Await keywords are instructing the compiler to do var sc = SynchronizationContext.Current; await Task.Run(async() => { // We are NOT on the UI thread. SynchronizationContext.Current is null Debug.WriteLine($"ThreadID: {Thread.CurrentThread.ManagedThreadId} SynchoronizationContext == null: {(SynchronizationContext.Current == null)}"); await ExploreAsyncAwait.AsyncAwait_A(); TaskCompletionSource <object> taskCompletionSource = new TaskCompletionSource <object>(); // Yet, using SynchronizationContext of the UI Thread and ExecutionContext we can run // in the same context as AsyncAwait_C sc.Post((o) => { // Spot A // We are now on the UI thread ExecutionContext.Run(ExploreAsyncAwait.executionContextC_Capture, (eo) => { // AsyncLocal now has the same values as AsyncAwait_C ExploreAsyncAwait.Log(11, Output); // And safely interact with UI controls Output("Exercise 17..."); }, null); taskCompletionSource.SetResult(null); }, null); // Without this we to Spot B before we get to Spot A await taskCompletionSource.Task; // Spot B }); }