Task.ContinueWith捕获调用线程上下文以继续吗?

时间:2013-08-19 11:28:43

标签: c# .net asynchronous task-parallel-library async-await

以下Test_Click是在UI线程(WindowsFormsSynchronizationContext)上运行的代码的简化版本:

void Test_Click(object sender, EventArgs e)
{
    var task = DoNavigationAsync();
    task.ContinueWith((t) =>
    {
        MessageBox.Show("Navigation done!");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

我应该明确指定TaskScheduler.FromCurrentSynchronizationContext()以确保继续操作将在同一个UI线程上执行吗?或者ContinueWith是否自动捕获执行上下文(因此,在这种情况下使TaskScheduler参数多余)?

我认为它默认情况下不会这样做(与await不同),但到目前为止我找不到在线资源来确认这一点。

1 个答案:

答案 0 :(得分:7)

默认情况下它不使用当前的同步上下文,而是使用TaskScheduler.Current,如以下反编译代码所示:

public Task ContinueWith(Action<Task<TResult>> continuationAction)
{
  StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  return this.ContinueWith(continuationAction, TaskScheduler.Current, new CancellationToken(), TaskContinuationOptions.None, ref stackMark);
}
如果任务是子任务,则

TaskScheduler.CurrentTaskScheduler.Default或当前任务的TaskScheduler。如果您不想遇到weird problems,请始终指定任务计划程序,或者更好,如果可以,请使用await