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