Task.ContinueWith是否捕获用于继续的调用线程上下文

本文关键字:调用 线程 上下文 继续 用于 ContinueWith 是否 Task | 更新日期: 2023-09-27 18:28:06

下面的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不同),但到目前为止,我找不到在线资源来确认这一点。

Task.ContinueWith是否捕获用于继续的调用线程上下文

默认情况下,它不使用当前同步上下文,而是使用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.Current是当前任务的TaskScheduler.Default或TaskScheduler。如果您不想遇到奇怪的问题,请始终指定任务调度程序,如果可以的话,最好使用await