Does Task.ContinueWith capture the calling thread context for continuation?
.net, async-await, asynchronous, c#, task-parallel-library
Solution
It doesn't use the current synchronization context by default, but `TaskScheduler.Current`, as seen in the following decompiled code:
public Task ContinueWith(Action<Task<TResult>> continuationAction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return this.ContinueWith(continuationAction, TaskScheduler.Current, new CancellationToken(), TaskContinuationOptions.None, ref stackMark);
}
`TaskScheduler.Current` is either `TaskScheduler.Default` or the TaskScheduler of the current task if the task is a child task. Always specify the task scheduler if you don't want to run into weird problems, or better, use `await` if you can.
Problem
The `Test_Click` below is a simplified version of code which runs on a UI thread (with WindowsFormsSynchronizationContext): ``` void Test_Click(object sender, EventArgs e) { var task = DoNavigationAsync(); task.ContinueWith((t) => { MessageBox.Show("Navigation done!"); }, TaskScheduler.FromCurrentSynchronizationContext()); } ``` Should I explicitly specify `TaskScheduler.FromCurrentSynchronizationContext()` to make sure the continuation action will be executed on the same UI thread? Or does `ContinueWith` capture the execution context automatically (thus, making `TaskScheduler` argument redundant in this case)? I assume it doesn't do it by default (unlike `await`), but so far I could not find an online resource to confirm this.