Async / Await vs Threads


100

In .Net 4.5 Microsoft ha aggiunto la nuova Async/Awaitfunzionalità per semplificare la codifica asincrona. Tuttavia, mi chiedo

  1. Può Async/Awaitsostituire completamente il vecchio modo di utilizzare Threads?
  2. È in Async/Awaitgrado di fare tutto ciò che Threadpuò fare in modo asincrono?
  3. Può Async/Awaitessere utilizzato solo con alcuni metodi come WebClient.DownloadStringAsynco posso convertire qualsiasi metodo sincrono per farlo utilizzare Async/Awaite non per bloccare il thread principale?

2
Thread e Async / Await sono funzionalità non correlate. Puoi combinarli, ma non devi.
dtb

2
Ho pensato che Async / Await stia facendo la stessa cosa che new Thread(() => {Some Work}).Start();sta facendo ?! non è vero?
Roman Ratskey

2
No. La tua ipotesi non è corretta. Potresti pensare a Task.Run (TPL), che spesso è combinato con Async / Await, ma è anche non correlato e non deve essere utilizzato con esso.
dtb

4
@dtb: Quindi quando usare Async / Await e quando usare i thread? Sono davvero confuso sulla differenza tra Task.Run, Thread.Start, Async / Await. Se potessi fornirmi una buona spiegazione che mi faccia capire le differenze tra loro sarei molto grato
Roman Ratskey

2
Async / await non crea o utilizza in altro modo i thread.
wRAR

Risposte:


78

può sostituire completamente il vecchio modo di usare i thread?

No. Un thread può fare molte più cose utili. Await è progettato specificamente per gestire qualcosa che richiede tempo, in genere una richiesta di I / O. Che tradizionalmente veniva eseguita con una richiamata quando la richiesta di I / O era completa. Scrivere codice che si basi su questi callback è abbastanza difficile, attendere lo semplifica notevolmente.

capace di fare cosa mai un thread può fare in modo asincrono?

Più o meno. Await si occupa solo di gestire il ritardo, altrimenti non fa nulla di quello che fa un thread. L' espressione await , ciò che è a destra della parola chiave wait, è ciò che fa il lavoro. Idealmente non usa affatto un thread, invia una richiesta del driver e una volta che il driver ha completato il trasferimento dei dati, genera un callback di notifica del completamento. La rete è di gran lunga l'utilizzo più comune, latenze di centinaia di millisecondi sono comuni e un inevitabile effetto collaterale dei servizi che si spostano dal desktop o da una LAN al "cloud". L'utilizzo di tali servizi in modo sincrono renderebbe un'interfaccia utente abbastanza non rispondente.

può essere utilizzato solo con alcuni metodi come WebClient.DownloadStringAsync

No. Puoi usarlo con qualsiasi metodo che restituisca un'attività. I metodi XxxxAsync () sono solo quelli precotti nel framework .NET per operazioni comuni che richiedono tempo. Come scaricare dati da un server web.


4
Nell'aspetto moderno di C # qual è l'approccio migliore per ottenere callback asincroni su API esterne?
bonCodigo

5
Trattata nell'ultimo paragrafo, usa un'attività.
Hans Passant

Mi aspetto qualcosa che un thread può fare che non può essere fatto tramite la programmazione asincrona come esempio.
Saeed Neamati

1
Potresti espandere su "Un thread può fare molte più cose utili"? Sarebbe utile comprendere le funzionalità fornite dai thread che asyncnon sono adatte.
Benjohn

1
Vale la pena menzionare await Task.Runper il lavoro legato alla CPU. Se ho capito bene, a volte ciò realizza ciò che si creerebbe altrimenti un thread o un lavoratore in background per fare.
ToolmakerSteve

15

La dichiarazione ufficiale su questo. Anche se dovresti capire le differenze tra thread e programmazione asincrona prima di sostituire ciecamente una cosa con altre.


Questa è come la prima risorsa che ho letto su Thread e Async / Await che è chiara e concisa.
Arman Bimatov

2
Questa risposta contiene solo un collegamento alla documentazione. Poiché il collegamento potrebbe diventare obsoleto, anche la risposta potrebbe diventare obsoleta o, peggio ancora, completamente inutile. Incoraggiamo gli utenti di Stack a pubblicare invece le parti pertinenti dei link direttamente nella loro domanda.
HimBromBeere

1
Purtroppo, la dichiarazione ufficiale non spiega quando farlo await Task.Run. C'è un breve accenno a Task.Run, ma non è chiaro. La linea di fondo è che di awaitper sé non farà eseguire in parallelo un'attività associata alla CPU, quindi tale lavoro dovrebbe essere fatto tramite await Task.Run.
ToolmakerSteve

1

La penso in questo modo (e penso che lo faccia anche Microsoft se guardi https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ) #threads )

Async / awaitèun modo rapido per eseguire del codice sul thread dell'applicazione principale con il vantaggio che il codice può sospendersi quando non ha lavoro da fare e restituire il focus al thread principale, "svegliarsi" sul thread principale quando c'è è un risultato da ottenere e poi ripassare l'elaborazione - avete indovinato - al thread principale. Pensala come un'istruzione GOTO basata su eventi in Basic che può passare il controllo avanti e indietro a una specifica linea di esecuzione.

Al contrario, un thread è un flusso di esecuzione separato che può essere eseguito con le proprie variabili ecc. Dove, con hardware sufficiente, l'esecuzione avviene in parallelo al thread principale.

Se hai un'applicazione GUI che scaricherà un singolo file e poi farà qualcosa con quel file quando viene scaricato, lo implementerei usando un metodo async / await.

Tuttavia, se la tua GUI deve scaricare 5000 file, creerei un thread di download di file per gestirlo poiché il thread principale della GUI potrebbe bloccarsi durante il trasferimento dell'esecuzione per gestire il download dei file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.