2013-08-19 12 views
8

Test_Click poniżej jest uproszczoną wersją kodu, który działa na wątku UI (z WindowsFormsSynchronizationContext):Czy Task.ContinueWith przechwytywanie kontekst wątku wywołania dla kontynuacji?

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

Mam jawnie określić TaskScheduler.FromCurrentSynchronizationContext() aby upewnić się, że kontynuacja działania będą realizowane w tym samym wątku UI? Czy też ContinueWith przechwytuje kontekst wykonania automatycznie (co sprawia, że ​​argument TaskScheduler jest w takim przypadku nadmiarowy)?

Zakładam, że nie robi tego domyślnie (w przeciwieństwie do await), ale do tej pory nie mogłem znaleźć zasobu online, aby to potwierdzić.

Odpowiedz

6

Nie używa bieżący kontekst synchronizacji domyślnie, ale TaskScheduler.Current, jak widać w poniższym kodzie decompiled:

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 jest albo TaskScheduler.Default lub TaskScheduler bieżącego zadania, jeśli zadanie to zadanie podrzędne. Zawsze należy określać harmonogram zadań, jeśli nie chcesz, aby uruchomić weird problems, lub lepiej, jeśli to możliwe, użyj await.

+0

Dziękuję, ma sens. Znalazłem również [this] (http://www.jaylee.org/post/2012/09/29/C-Async-Tips-and-Tricks-Part-3-Tasks-and-synchronization-Context .aspx), powiązane i bardzo pomocne. – Noseratio

+0

Jeszcze łatwiej znaleźć teraz ze źródłem referencji: http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs#27c5b7fbe5caaa18 W związku z tym, proszę wyjaśnić, co robi StackCrawlMark? – Kakira

Powiązane problemy