async await

Programmazione asincrona con async – await (parte 2)

Dopo il post introduttivo sulla programmazione asincrona in .NET, analizziamo le parole chiave asyncawait, introdotte a partire da C# 5.0. Async e Await consentono di scrivere codice asincrono in modo semplice: il codice  risulta molto simile a quello sincrono, con tutti i vantaggi che ne derivano in termini di gestione di thread. Nella programmazione asincrona vengono generati thread separati, che non permetto di effettuare chiamate non bloccanti.

E’ proprio la modalità in cui vengono eseguiti i thread che differenzia la programmazione asincrona da quella sincrona: se l’esecuzione continua senza aspettare il termine di altre operazioni (tipicamente con un tempo di esecuzione più lungo rispetto al chiamante), siamo in presenza di codice asincrono. Al contrario, se il nostro codice rimane in attesa della funzione chiamata, siamo in presenza di codice bloccante (sincrono).

La scrittura di codice asincrono consente di liberare il thread che ha effettuato la chiamata  del metodo asincrono. Questo comportamento consente, ad esempio, di non bloccare la UI di un’applicazione rendendola inutilizzabile (freezata) durante l’elaborazione.

A partire da C# 5 .0 il team di sviluppo di Microsoft ha aggiunto alcune funzionalità per semplificare la scrittura di codice asincrono: 

  • la parola chiave async
  • la parola chiave await
  • miglioramenti all’interno del framework

Le modifiche consentono di scrivere codice asincrono senza dover ricorrere a pattern complessi (ancora presenti nel framework, ma utilizzabili solo all’occorrenza e in casi particolari).

Async – Await funzionamento

AsyncAwait sono il meccanismo che consente di definire che cosa accade al termine di un’operazione “long-running”, mantenendo il codice leggibile e garantendone l’esecuzione asincrona. Consideriamo il seguente codice, che istanzia un oggetto di tipo WebClient ed effettua il download di un pagina (sotto forma di stringa):

Il codice è di tipo sincrono, e quindi bloccante per l’eventuale UI.  Riscriviamo il codice precedente utilizzando i metodo asincroni: 

Apparentemente il codice sembra uguale, ma il funzionamento è nettamente differente. Quando viene raggiunta la parola chiave await viene iniziato il download. Ma non nel thread corrente. Dal thread corrente viene effettuato un return alla funzione che ha richiamato il metodo e le risorse vengono liberate. Solo al termine del download verrà ripresa l’esecuzione. 

Hibernating e Resuming di un metodo

Quando il codice raggiunge la parola chiave await si verificano le seguenti condizioni: 

  • il thread corrente viene rilasciato, per rendere il codice asincrono. Questo significa da un un punto di vista del codice sincrono che il metodo ritorna
  • quanto il Task, atteso  tramite await, termina la sua esecuzione, il metodo può riprendere come se si trattasse di codice sincrono

Per ottenere questo comportamento, il thread deve entrare in una sorta di pausa quando incontra la keyword await e riprendere il normale flusso successivamente.

Un pò come avviene quando un personal computer entra nello stato di ibernazione: lo stato corrente viene memorizzato per poi essere ripreso successivamente. 

Pubblicato da

Andrea Merlin

Laureato in informatica, diversi corsi di specializzazione legati allo Sviluppo Software e alla Computer forensics. Appassionato di nuove tecnologie, amo la programmazione, la Business Intelligence e tematiche legate alla Privacy.Sempre alla ricerca di nuove idee, stimoli … e progetti da seguire!Amo trascorrere il tempo libero in Val Borbera, un piccolo angolo del Piemonte, in provincia di Alessandria.