2013-08-19 34 views
8

Test_Click下面是代码的简化版本,其运行在UI线程(与WindowsFormsSynchronizationContext):是否Task.ContinueWith捕获调用线程上下文以便继续?

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

回答

6

它不使用默认的当前同步环境,但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如果该任务是一个孩子的任务。如果您不想运行到weird problems或更好,请始终指定任务计划程序,如果可以的话,请使用await

+0

谢谢,非常有道理。我也发现[this](http://www.jaylee.org/post/2012/09/29/C-Async-Tips-and-Tricks-Part-3-Tasks-and-the-Synchronization-Context .aspx),相关且非常有帮助。 – Noseratio

+0

更容易找到与参考来源:http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs#27c5b7fbe5caaa18 这就是说,你可以请解释什么StackCrawlMark呢? – Kakira