Switching Context With Async

Whenever an await is encountered in the code, a context is captured, which is later used when the promise is completed and ready to continue. If the method is called by the UI thread, usually, the context could be UI context, unless the awaited method itself creates a new thread. This can be demonstrated in the following example.

 

async Task DoAsync()
{
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    await Task.Delay(TimeSpan.FromSeconds(3));
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);

}
The ThreadID displayed would be the same. However, there could be scenarios where you might be interested to actually switch the context. The framework provides an easy way to do same, using the ConfigureAwait method, which accepts a boolean which dictates whether to continue on captured context. Let’s change the above code and check the new output.

 

async Task DoAsync()
{
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);

}
The ThreadIDs would be different in this case.

Stephen Clearly mentions a deadlock situation in his famous book, where ConfigureAwait helps in breaking the deadlock. Let’s consider the deadlock situation first.

private async void button1_Click(object sender, EventArgs e)
{
Task temp = DoAsync();
Debug.WriteLine("Continue");
temp.Wait();
Debug.WriteLine("Not Deadlock");
}

async Task DoAsync()
{
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.Delay(TimeSpan.FromSeconds(3));
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);

}

The above code would end up in a deadlock. This is because, in the DoAsync Method, the captured context in which the execution needs to continue, has a thread which is already blocked by the Wait Method in the calling Button_Click event. Since the context only allows a single thread to continue, this would result in a deadlock situation. This could be resolved if we switch context in the await method.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s