Search code examples
c#.netasync-awaittask-parallel-librarysynchronizationcontext

SynchronizationContext - strange behavior


public static void Init()
{
    //var task = GetSource1();
    //var task = GetSource2();
    //var task = GetSource3();
    var task = MyClient();
    MessageBox.Show(task.Result);
}

private static async Task<string> GetSource1()
{
    var sourceTask = WebClient();
    sourceTask.ConfigureAwait(false);
    return await sourceTask;
}

private static async Task<string> GetSource2()
{
    var sourceTask = MyClient();
    sourceTask.ConfigureAwait(true);
    return await sourceTask;
}

private static async Task<string> GetSource3()
{
    var sourceTask = MyClient();
    sourceTask.ConfigureAwait(false);
    return await sourceTask;
}

private static async Task<string> WebClient()
{
    return await new WebClient().DownloadStringTaskAsync("http://4pda.ru").ConfigureAwait(false);
}

private static Task<string> MyClient()
{
    var t = new Task<string>(() => new WebClient().DownloadString("http://4pda.ru"));
    t.ConfigureAwait(false);
    t.Start();
    return t;
}

This code works fine. I get the source in MessageBox. However why I get deadlock when I use var task = GetSource3()? I thought that it must works because I use ConfigureAwait(false) and avoid the context switching


Solution

  • ConfigureAwait is a pure method. It returns a value but has no effect on its own. It returns a customized awaitable (ConfiguredTaskAwaitable) that you need to await:

    await task.ConfigureAwait();
    

    However, this isn't how you should handle deadlocks. It's a precaution but you should avoid blocking on asynchronous code to begin with.