本文介绍了是否Task.ContinueWith捕捉延续调用线程上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Test_Click 下面是code的简化版本,在UI线程上运行(与 WindowsFormsSynchronizationContext ):

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());
}

我应该明确地指定 TaskScheduler.FromCurrentSynchronizationContext(),以确保持续的行动将相同的用户界面线程上执行?还是 ContinueWith 自动捕捉执行环境(从而,使的TaskScheduler 参数在这种情况下,多余的)?

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.

推荐答案

它不使用默认当前同步上下文,但 TaskScheduler.Current ,如在以下反编译code:

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 TaskScheduler.Default 或当前任务的TaskScheduler如果任务为子任务。始终指定任务调度器,如果你不想碰到weird 的问题,或者更好,使用等待如果你能。

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.

这篇关于是否Task.ContinueWith捕捉延续调用线程上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 16:10