Async / Await vs Threads


100

W .Net 4.5 Microsoft dodał nową Async/Awaitfunkcję upraszczającą asynchroniczne kodowanie. Zastanawiam się jednak

  1. Czy można Async/Awaitcałkowicie zastąpić stary sposób użytkowania Threads?
  2. Czy jest w Async/Awaitstanie robić wszystko, co Threadmoże, asynchronicznie?
  3. Czy Async/Awaitmożna używać tylko z niektórymi metodami, takimi jak, WebClient.DownloadStringAsyncczy mogę przekonwertować dowolną metodę synchroniczną, aby była używana, Async/Awaita nie do blokowania głównego wątku?

2
Wątki i Async / Await to niepowiązane funkcje. Możesz je łączyć, ale nie musisz.
dtb

2
Myślałem, że Async / Await robi to samo co new Thread(() => {Some Work}).Start();robi ?! prawda?
Roman Ratskey

2
Nie. Twoje założenie nie jest poprawne. Możesz pomyśleć o Task.Run (TPL), który często jest łączony z Async / Await, ale jest również niepowiązany i nie musi być z nim używany.
dtb

4
@dtb: Więc kiedy używać Async / Await, a kiedy używać Threads? Jestem naprawdę zdezorientowany różnicą między Task.Run, Thread.Start, Async / Await. Gdybyś mógł podać mi dobre wyjaśnienie, które pozwala mi zrozumieć różnice między nimi, byłbym bardzo wdzięczny
Roman Ratskey

2
Async / await nie tworzy ani w żaden inny sposób nie używa wątków.
WRAR

Odpowiedzi:


79

czy może całkowicie zastąpić stary sposób korzystania z wątków?

Nie. Wątek może zrobić o wiele więcej przydatnych rzeczy. Oczekiwanie jest specjalnie zaprojektowane do radzenia sobie z czymś , co wymaga czasu, najczęściej jest to żądanie we / wy. Co tradycyjnie było wykonywane z wywołaniem zwrotnym po zakończeniu żądania we / wy. Pisanie kodu, który opiera się na tych wywołaniach zwrotnych jest dość trudne, czekaj znacznie to upraszcza.

jest w stanie zrobić wszystko, co wątek może zrobić asynchronicznie?

W przybliżeniu. Oczekiwanie zajmuje się tylko opóźnieniem, w przeciwnym razie nie robi nic, co robi wątek. Wyrażenie await , które znajduje się po prawej stronie słowa kluczowego await, jest tym, co wykonuje zadanie. Idealnie byłoby, gdyby w ogóle nie używał wątku, wysyła żądanie sterownika, a gdy sterownik zakończy transfer danych, generuje wywołanie zwrotne z powiadomieniem o zakończeniu. Zdecydowanie najpowszechniejszym zastosowaniem jest połączenie sieciowe, powszechne są opóźnienia rzędu setek milisekund i nieunikniony efekt uboczny przenoszenia usług z komputera stacjonarnego lub sieci LAN do „chmury”. Synchroniczne korzystanie z takich usług spowodowałoby, że interfejs użytkownika nie odpowiadałby.

można używać tylko z niektórymi metodami, takimi jak WebClient.DownloadStringAsync

Nie. Możesz go używać z dowolną metodą, która zwraca zadanie. Metody XxxxAsync () to tylko wstępnie ugotowane metody w środowisku .NET dla typowych operacji, które wymagają czasu. Podobnie jak pobieranie danych z serwera internetowego.


4
W nowoczesnym aspekcie C #, jakie jest najlepsze podejście do osiągnięcia Async-Callback w zewnętrznych interfejsach API?
bonCodigo

5
Omówione w ostatnim akapicie użyj zadania.
Hans Passant

Spodziewałbym się czegoś, co może zrobić wątek, czego nie można zrobić za pomocą programowania asynchronicznego jako przykładu.
Saeed Neamati

1
Czy mógłbyś rozwinąć temat „Wątek może zrobić o wiele więcej pożytecznych rzeczy.”? Przydałoby się zrozumienie funkcji, które zapewniają wątki, które asyncsą nieodpowiednie.
Benjohn

1
Warto wspomnieć await Task.Runo pracy związanej z procesorem. Jeśli dobrze rozumiem, czasami osiąga się to, co w innym przypadku stworzyłoby się wątek lub pracownik w tle.
ToolmakerSteve

15

Oficjalne oświadczenie w tej sprawie. Chociaż powinieneś zrozumieć różnice między wątkami i programowaniem asynchronicznym, zanim ślepo zastąpisz jedną rzecz innymi.


To jest jak pierwszy zasób, który przeczytałem o Threads i Async / Await, który jest jasny i zwięzły.
Arman Bimatov

2
Ta odpowiedź zawiera tylko link do dokumentacji. Ponieważ łącze może być nieaktualne, odpowiedź może również stać się nieaktualna - lub co gorsza - całkowicie bezużyteczna. Zachęcamy użytkowników Stack do umieszczania odpowiednich części linków bezpośrednio w ich pytaniach.
HimBromBeere

1
Niestety oficjalne oświadczenie nie wyjaśnia, kiedy należy to zrobić await Task.Run. Jest krótka wzmianka o Task.Run, ale nie jest to jasne. Najważniejsze jest to, że awaitsamo w sobie nie spowoduje równoległego uruchomienia zadania związanego z procesorem, dlatego taka praca powinna być wykonywana za pośrednictwem await Task.Run.
ToolmakerSteve

2

Myślę o tym w ten sposób (i myślę, że Microsoft też to robi, jeśli spojrzysz na https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ) #threads )

Async / await to szybki sposób na uruchomienie kodu w głównym wątku aplikacji z tą zaletą, że kod może się zawiesić, gdy nie ma do wykonania żadnej pracy i powrócić do głównego wątku, „obudź się” w głównym wątku, gdy już tam jest jest wynikiem, który należy uzyskać, a następnie przekazać przetwarzanie z powrotem - zgadłeś - do głównego wątku. Pomyśl o tym jak o instrukcji GOTO opartej na zdarzeniach w Basicu, która może przekazywać sterowanie tam iz powrotem do określonej linii wykonania.

W przeciwieństwie do tego wątek jest oddzielnym strumieniem wykonywania, który może działać z własnymi zmiennymi itp., Gdzie - przy wystarczającym sprzęcie - wykonywanie odbywa się równolegle do głównego wątku.

Jeśli masz aplikację GUI, która ma zamiar pobrać pojedynczy plik, a następnie zrobić coś z tym plikiem po jego pobraniu - zaimplementowałbym to za pomocą metody async / await.

Jeśli jednak twój GUI musi pobrać 5000 plików - utworzyłbym wątek pobierania plików, aby to obsłużyć, ponieważ główny wątek GUI może zawiesić się podczas przesyłania wykonywania w celu obsługi pobierania plików.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.