Ho affermato la mia comprensione asincrona/attendo in un paio di occasioni, spesso discutendo se sia corretto o meno. Lo apprezzerei davvero se qualcuno potesse confermare o negare la mia comprensione e chiarire eventuali equivoci in modo da non diffondere informazioni errate.La mia comprensione dell'async/dell'attesa, di come funziona e dei suoi benefici, è corretta?
ad alto livello intesa
async
/await
è un modo per evitare di callback inferno durante la scrittura di codice asincrono. Un thread che sta eseguendo un metodo asincrono tornerà al pool di thread quando incontra uno await
e prenderà l'esecuzione una volta completata l'operazione attesa.
basso livello intesa
Il JIT sarà dividere un metodi asincroni in parti discrete intorno await
punti, permettendo il rientro nel metodo con lo stato del metodo conservato. Sotto le coperte si tratta di una sorta di macchina statale.
Relazione con il Concurrency
async
/await
non implica alcun tipo di concorrenza. Un'applicazione scritta usando async
/await
potrebbe essere interamente single-threaded mentre continua a raccogliere tutti i vantaggi, molto come node.js anche se con callback. A differenza di node.js, .NET è multithreading in modo da avere async
/await
, si ottengono i vantaggi dell'IO non bloccante senza utilizzare i callback, pur avendo più thread di esecuzione.
I benefici
async
/await
consente di liberare le discussioni per fare altre cose in attesa di IO per il completamento. Può anche essere utilizzato insieme allo TPL per eseguire il lavoro con CPU su più thread o fuori dal thread dell'interfaccia utente.
Per beneficiare da non bloccante IO, i metodi asincroni devono essere costruito su di API che effettivamente sfruttano non bloccante IO che vengono infine forniti dal sistema operativo.
Misuse
Questo è il più grande punto di contesa nella mia comprensione. Molte persone credono che il wrapping di un'operazione di blocco in un Task
e l'utilizzo di async
/await
determineranno un aumento delle prestazioni. Creando un thread aggiuntivo per gestire un'operazione, restituendo il thread originale al pool di thread e quindi riprendendo il metodo originale dopo il completamento dell'attività, tutto ciò che si sta verificando sono interruttori di contesto non necessari mentre non si liberano realmente i thread per eseguire altre operazioni. Anche se questo non è tanto un uso improprio di async
/await
come è il TPL, questa mentalità sembra derivare da un malinteso di async
/await
.
La tua comprensione è perfetta, corretta al 100%. –
È il compilatore, piuttosto che il jitter, che crea la macchina a stati; non esiste qualcosa come "attendere" al livello sottostante. È possibile esaminare le classi prodotte se si utilizza ILSpy o simili. –
Informazioni sull'uso improprio: se il tuo thread non ha nient'altro da fare, in effetti dovresti lasciargli il tuo thread. Buf se il tuo thread ha altre cose significative da fare, ad esempio mantieni la tua interfaccia utente reattiva, allora è saggio fare il lavoro pesante in un'attività separata –