This slides explains why ConfigureAwait(false) needs to be called when we use async await. This slides is based on the following blog by Microsoft.
https://devblogs.microsoft.com/dotnet/configureawait-faq/
Size: 667.75 KB
Language: en
Added: Feb 01, 2020
Slides: 27 pages
Slide Content
Understanding ConfigureAwait (false) Shuhei Eda
If you’ve already read this blog , Finish reading this slides. Do not waste your time!
Agenda Understanding SynchronizationContext and TaskScheduler How do SynchronizationContext and TaskScheduler relate to await? Problems of Posting callbacks What does ConfigureAwait (false) do?
Understanding SynchronizationContext and TaskScheduler
Official definition of SynchronizationContext Official document says… “Provides the basic functionality for propagating a synchronization context in various synchronization models.” Too abstract!!!
Easier explanation of SynchronizationContext Provides Post method which passes a delegate(callback, action..) from one thread to another Base method just enqueues a callback into ThreadPool Current Thread ThreadPool Thread Post
Sample code of SynchronizationContext Output ThreadId : 1 Action Called ThreadId : 11
Derived-Type of SynchronizationContext Some frameworks have a specific thread E.X. Winforms sets Derived-Type of SynchronizationContext to allow the context to be brought onto the UI thread. The callback is invoked on UI thread Current Thread UI Thread Post ( BeginInvoke )
Sample code of SynchronizationContext Output ThreadId : 1 Action Called ThreadId : 1
TaskScheduler Very Roughly Speaking: Task’s version of SynchronizationContext Provides “ QueueTask ” method which enqueues tasks to the Thread pool. If the LongRunning option is true, it creates a new thread.
How do SynchronizationContext and TaskScheduler relate to await?
Write asynchronous code (Before .NET 4.0) Use TaskScheduler Use SynchronizationContext Thread 1 Thread 2 ContinueWith GetStringAsync Post back
Write asynchronous code (Before .NET 4.0) Use TaskScheduler Use SynchronizationContext Thread 1 Thread 2 ContinueWith GetStringAsync SynchronizationContext is captured! Post back
Write asynchronous code (After .NET 4.5) Can use async await keyword ContinueWith GetStringAsync Post back Thread 1 Thread 2
Detailed capturing behavior
Problems of Posting callbacks
Problems of Posting callbacks Deadlock If an original thread calls Wait(), Result, or GetResult (), it gets blocked until the thread running the task finishes. The subsequent thread waits until the original thread becomes available. Performance Enqueueing the callback to another thread is an expensive operation Cannot do post back Thread 1 Thread 2 Blocking HeavyAsync () .Result Doing heavy tasks Deadlock!
Problems of Posting callbacks Deadlock If an original thread calls Wait(), Result, or GetResult (), it gets blocked until the thread running the task finishes. The subsequent thread waits until the original thread becomes available. Performance Enqueueing the callback to another thread is an expensive operation Cannot do post back Thread 1 Thread 2 Blocking HeavyAsync () .Result Doing heavy tasks I will restart after Thread 2’s method is done. Deadlock!
Problems of Posting callbacks Deadlock If an original thread calls Wait(), Result, or GetResult (), it gets blocked until the thread running the task finishes. The subsequent thread waits until the original thread becomes available. Performance Enqueueing the callback to another thread is an expensive operation Cannot do post back Thread 1 Thread 2 Blocking HeavyAsync () .Result Doing heavy tasks I will restart after Thread 2’s method is done. I will do post-back when Thread1 becomes available Deadlock!
Sample code of deadlock Result: 1 : Main Start 1 : ChildSampleAsync Start This block is trying to be executed in Thread1, but Thread 1 is blocked, so the deadlock occurs. Since the “Result” method is called, Thread1 gets blocked
What does ConfigureAwait (false) do?
ConfigureAwait (false) = Prevents capturing SynchronizationContext Sample code of capturing process ConfigureAwait (false) bypasses the following block of code.
If ConfigureAwait (false) is called.. It will not post the callback. The code block after the “await” keyword will continue running on the same thread. Thread 1 Thread 2 Blocking HeavyAsync () .Result Doing heavy tasks No post happens and the method is processed in the same thread.
Sample code of NON-deadlock Result: 1 : Main Start 1 : ChildSampleAsync Start 7 : ChildSampleAsync End 1 : Main End This code block runs on another thread, not in original thread. ConfiureAwait (false) is called.
Advantages of calling ConfigureAwait (false) Avoiding deadlocks Performance Since no queueing of the callback occurs.
Guidance of using ConfigureAwait (false) Should use ConfigureAwait (false) general-purpose libraries ASP.NET Core Console App Should NOT use ConfigureAwait (false) Win Forms ASP.NET ( HttpContext.Current might be badly affected ) WPF Silverlight