Async/Await: Unexpected behaviour of ConfigureAwait

asp.net, asp.net-mvc, async-await, c#, task-parallel-library

Solution

If you use `await task.ConfigureAwait(false)`, then the rest of that method (and whatever you call from there) will not execute on the original context. But this won't affect any code higher up in the logical call tree.

And I think this is the only logical way to do it. If the code higher up has to be executed on the original context (which is quite common), then `ConfigureAwait()` somewhere deep inside library code really shouldn't affect it.

To make this more concrete, the following simple example of using `await` in Winforms wouldn't work if `ConfigureAwait()` behaved according to you:

async void ButtonClicked(object sender, EventArgs e)
{
    textBlock.Text = "Downloading";
    await DownloadAsync();
    textBlock.Text = "Finished";
}

async Task DownloadAsync()
{
    data = await new HttpClient().GetStringAsync(url).ConfigureAwait(false);
}

Problem

If you execute the following code in ASP.NET MVC, you can see in Debugging Window that it will correctly restore the thread's culture after `await`, even if ManagedThreadId changes: ``` public async Task<ActionResult> Index() { Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); await SomeMethod(); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); return View(); } private async Task SomeMethod() { await Task.Delay(100).ConfigureAwait(false); } ``` Then I just move ConfigureAwait(false) from SomeMethod() to Index(), except for this, it's the same code as above: ``` public async Task<ActionResult> Index() { Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); await SomeMethod().ConfigureAwait(false); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); Debug.WriteLine(Thread.CurrentThread.CurrentUICulture); return View(); } private async Task SomeMethod() { await Task.Delay(100); } ``` Now it doesn't restore my culture but always set it to `new CultureInfo("en-US")`. But I expect that using both methods, the result must be the same. It's absolutely unclear, why it's happening.

Original source