2013-06-04 12 views
16

Nadal uczę się całej koncepcji zadań i licencji OC. Z mojego obecnego rozumienia funkcje SynchronizationContext (jeśli są obecne) są używane przez await do wysłania zadania "gdzieś". Z drugiej strony funkcje w klasie Task nie używają kontekstu, prawda?Jak uzyskać zadanie, które korzysta z Kontakty synchronizacji? A w jaki sposób używasz SynchronizationContext?

Tak na przykład Task.Run(...) będzie zawsze wywoływał akcję w wątku roboczym puli wątków i całkowicie ignoruje numer SynchronizationContext.Current. await Foobar() użyłoby kontekstu do wykonania wygenerowanego zadania po await?

Jeśli to prawda, moje pytanie brzmi: Jak uzyskać Task, który faktycznie uruchamia akcję, ale jest wywoływany za pomocą SynchronizationContext.Current.Send/Post?

Czy ktoś może polecić dobre wprowadzenie do SynchronizationContext, zwłaszcza kiedy i jak są używane przez resztę schematu? MSDN wydaje się być bardzo cichy na temat klasy. Najlepsze hity Google (here i here) wydają się być dostosowane tylko do wysyłania formularzy Windows Forms. Stephen Cleary napisał: an article, co jest miłe, aby dowiedzieć się, jakie konteksty już istnieją i jak działają, ale brakuje mi zrozumienia, gdzie i kiedy są one rzeczywiście używane.

Odpowiedz

26

Jak mogę otrzymać to zadanie, które rzeczywiście prowadzi działania, ale jest wywoływane za pomocą SynchronizationContext.Current.Send/Post?

Zastosowanie specjalny harmonogram zadań:

Task.Factory.StartNew(
    () => {}, // this will use current synchronization context 
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext()); 

A może ktoś polecić dobry wstęp do SynchronizationContext

spojrzeć na artykuł It's All About the SynchronizationContext Stephen Cleary.

+0

ah, nice. dzięki. Czy jest jakaś różnica między 'Task.Run' i' Task.Factory.StartNew'? (Mam na myśli ... każdą inną różnicę niż to, że '' Task.Factory.StartNew' akceptuje jakiś parametr, którego 'Task.Run' nie ma";)) – Imi

+0

Nie, nie ma między nimi żadnej różnicy. – Dennis

+0

_Spójrz na ten artykuł. Dziękujemy za link. Przeczytałem już ten artykuł i powiązałem go z moim pytaniem - bardzo dobre do zrozumienia, jakie konteksty istnieją i dlaczego zostały wprowadzone w pierwszej kolejności. Jakieś inne dobre źródła, może wchodząc w szczegóły, która klasa używa kontekstów, kiedy? Czy mogę podejść do TPL niesłusznie i powinienem przeczytać o "Dlaczego właściwie nigdy nie powinienem się tym przejmować"? :RE. – Imi

18

Jak uczysz się tego, ważne jest, aby podkreślić, że Taskstosowany przez TPL jest zupełnie inny niż Taskużywanych przez async/czekają, mimo że są one tego samego typu. Na przykład TPL zwykle używa zadań nadrzędnych/podrzędnych, ale nie ma takiej możliwości.

TPL używa zadań harmonogramów do wykonywania swoich zadań. Jak zauważył Dennis, TaskScheduler.FromCurrentSynchronizationContext da Ci harmonogram zadań, który używa Post na bieżącym SynchronizationContext, aby wykonać swoje zadanie.

async/await zwykle nie używa harmonogramów zadań. Na swoim blogu mam wprowadzenie async/await post, które zawiera informacje kontekstowe, ale wspominam o tym krótko w moim MSDN article (jednak łatwo to przeoczyć). Zasadniczo, gdy metoda async zawiesza się na await, domyślnie przechwytuje bieżącą wartość SynchronizationContext (chyba że jest to null, w takim przypadku przechwyci bieżącą TaskScheduler). Po wznowieniu metody async wznawia ona wykonywanie w tym kontekście.

Dennis zwrócił uwagę na sposób TPL na zaplanowanie zadania na bieżące SynchronizationContext, ale w świecie async/await takie podejście nie jest konieczne. Przeciwnie, można wyraźnie zaplanować zadania do puli wątków poprzez Task.Run:

async Task MyMethodAsync() 
{ 
    // Whee, on a SynchronizationContext here! 
    await Task.Run(() => { }); // Ooo, on the thread pool! 
    // Back on the SynchronizationContext ... 
    // ... automagically! 
} 

pisałam SynchronizationContext artykuł właśnie dlatego docs MSDN były tak brakuje. Mam numer little more information on my blog, ale wszystkie ważne elementy znajdują się w artykule MSDN. Wiele typów używa raczej AsyncOperation niż SynchronizationContext bezpośrednio; najlepsza dokumentacja do tego jest buried under the EAP docs (section "Threading and Context"). Ale powinienem również zwrócić uwagę, że EAP jest przestarzały z powodu async/await, więc nie pisałbym kodu przy użyciu AsyncOperation (lub SynchronizationContext) - chyba że faktycznie byłam , pisząc własnąSynchronizationContext.

+0

_SynchronizationContext (chyba że jest pusty, w takim przypadku będzie przechwytywał bieżący TaskScheduler) ._ Interesujące ... Właściwie, podczas czytania w TaskScheduler, zaczynam myśleć, że TaskScheduler - a nie Kontrast Synchronization - jest tym, czego potrzebuję dla mojego oryginalny problem (nie opisany tutaj). Czy masz dobre referencje TaskSchedulers kontra SynchronizationContexts i jaka to różnica? (Patrząc na MSDN, wydaje się, że oba są odpowiedzialne za przekazywanie zadań na wątki, prawda?) – Imi

+0

'SynchronizationContext' został opracowany w .NET 2.0 i służy do planowania delegatów (synchronicznie lub asynchronicznie). 'TaskScheduler' został wprowadzony w .NET 4.0 i służy do planowania zadań (asynchronicznie). –

Powiązane problemy