Why isn't SyncContext restored after await without ConfigureAwait(false)

89 views Asked by At

I have been reading articles on async/await and SynchronisationContext trying to understand exactly when there will be threading/deadlocking issues.

To test this out I created a template WPF app with a single button (named myButton) and printed the thread and SyncContext at various points.

Why are there 4 different SynchronisationContexts? Or at least, why are there 4 different hashes for SynchronisationContext?

In other code examples (such as this SO post) the SyncContext hash is restored following the awaited Task. What is different here?

I would have expected this sort of behaviour if I had used .ConfigureAwait(false) as then the execution would not have been required to return on the captured context.


Code (adapted from code in same SO post referenced above):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        logCurrentSyncContext("0.1");   // Context 1
        await Experiment();
        logCurrentSyncContext("0.2");   // Context 4
    }

    public async Task Experiment()
    {
        logCurrentSyncContext("1.1");   // Context 1
        var a = await DoSomething();
        logCurrentSyncContext("1.2");   // Context 3
    }

    public async Task<bool> DoSomething()
    {
        logCurrentSyncContext("2.1");   // Context 1
        await Task.Delay(500);
        logCurrentSyncContext("2.2");   // Context 2
        myButton.Content = "OK";
        logCurrentSyncContext("2.3");   // Context 2
        return true;
    }

    private static void logCurrentSyncContext(object marker)
    {
        var sc = SynchronizationContext.Current;
        System.Diagnostics.Debug.WriteLine(marker + " Thread: " + Environment.CurrentManagedThreadId + " SyncContext: " + (sc == null ? "null" : sc.GetHashCode().ToString()));
    }
}

Results:

0.1 Thread: 1 SyncContext: 24981566   // Call this Context 1
1.1 Thread: 1 SyncContext: 24981566
2.1 Thread: 1 SyncContext: 24981566
2.2 Thread: 1 SyncContext: 12809933   // Call this Context 2
2.3 Thread: 1 SyncContext: 12809933
1.2 Thread: 1 SyncContext: 48180537   // Call this Context 3
0.2 Thread: 1 SyncContext: 30971651   // Call this Context 4
0

There are 0 answers