2013-08-19 36 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