1. Async/Await make it simple!!
Massimo Bonanni
http://codetailor.blogspot.com
massimo.bonanni@domusdotnet.org
@massimobonanni
2. Agenda
Cos’è e cosa non è «Asincrono»
L’asincrono prima di Async/Await
Cosa sono Async e Await
Cosa fanno Async/Await
La «magia» del compilatore
Async/Await ed i thread
Cancellation e Progress in Async/Await
Riutilizzare vecchio codice
Async/Await e Windows Store Apps
Async/Await e il framework 4.0
3. Cos’è «Asincrono»
«Il lavoro di un cameriere
consiste nell’attendere ad un
tavolo finché il cliente non ha
terminato il pasto! Se vuoi
servire due tavoli, hai bisogno
di due camerieri!»
«Non hai bisogno di due camerieri! Un unico
cameriere può facilmente servire due tavoli
contemporaneamente, semplicemente
passando da uno all’altro»
4. Cosè “Asincrono”
Pensiamo al cameriere come un thread, e il tavolo
come un metodo da eseguire.
In un approccio tradizionale, per eseguire due
compiti contemporaneamente (ad esempio,
mantenere l'interfaccia utente sensibile durante il
download di un file), si sarebbero utilizzati due
thread.
Creare thread è inefficiente (assumere camerieri
noleggio) e si deve combattere parecchio per
aggiornare le UI dal thread in background (fare in
modo che i camerieri non siano in conflitto).
5. Asincrono vs Sincrono: perchè e come!
asincrono [a-sìn-cro-no] agg.
«dispositivo che opera senza un riferimento
temporale di sincronizzazione rispetto a un
altro dispositivo»
↓
«non [a] nello stesso tempo»
6. Cosa non è «Asincrono»
Asincrono non significa «eseguito in
background»!!
Eseguire un’operazione in background è
una delle possibili implementazioni di
asincrono, non l’unica e, a volte, neanche la
migliore
7. Asincrono vs Sincrono: perchè e
come!
Un approccio asincrono garantisce che le
nostre interfacce grafiche siano:
• Responsive
• Non bloccate da logiche di accesso ai dati
(sia per dati locali che remoti)
9. L’asincrono prima di Async/Await
Il framework .NET, prima dell’introduzione
della TPL, prevedeva due modalità di
implementazione del pattern asincrono:
• Asynchronous Programming Model
(APM)
• Event-based Asynchronous Pattern
(EAP)
10. Asynchronous Programming Model
APM si basa sul design pattern
IAsyncResult e prevede che le operazioni
asincrone siano individuate da una coppia di
metodi caratterizzati dai prefissi Begin/End.
Un esempio è dato dalla classe FileStream
con i suoi metodi BeginRead e EndRead.
11. Asynchronous Programming Model
Per utilizzare questo tipo di chiamate asincrone
sono necessari i seguenti step:
1. il chiamante invoca il metodo Begin passando una
funzione di callback;
2. l’esecuzione dell’operazione asincrona avviene in
un thread separato;
3. al termine dell’operazione è richiamata la callback
passata dal chiamante;
4. il chiamante conclude l’operazione asincrona
invocando il metodo End (che restituisce i dati di
ritorno del metodo).
12. Event-based Asynchronous
Pattern
Le operazioni asincrone sono rappresentate da una
coppia Metodo/Evento.
Il metodo è identificato dal suffisso Async mentre
l’evento dal suffisso Completed.
Nell’argomento dell’evento sono, generalmente,
riportati i risultati dell’operazione.
Un esempio presente nel framework .NET è il
metodo DownloadStringAsync (e il corrispettivo
evento DownloadStringCompleted) della classe
WebClient
13. Event-based Asynchronous
Pattern
EAP è stato introdotto con la versione 2.0 del
framework .NET.
I passi eseguiti dal chiamante sono:
1. il chiamante si sottoscrive all’evento di
completamento dell’operazione (Completed);
2. il chiamante esegue il metodo Async;
3. il metodo esegue l’operazione in un thread
separato;
4. al termine dell’operazione viene sollevato l’evento
Completed e il chiamante viene avvertito del
completamento.
15. Cosa sono Async/Await
Vantaggi di Async/Await:
1. Permette di scrivere codice asincrono con
una struttura che sembra quella di un codice
sincrono;
2. In caso di aggiornamenti dell’interfaccia non
è necessario utilizzare un
SynchronizationContext;
3. La gestione delle eccezioni avviene in
maniera del tutto analoga ad un codice
sincrono.
16. Cosa sono Async/Await
La parola chiave Async indica al
compilatore che un metodo (sia esso
classico che una lamdba expression) è
asicrono e che, quindi, al suo interno
possono trovare posto dei punti di
“sospensione” identificati dalla parola
chiave Await.
17. Cosa sono Async/Await
La parola chiave Await indica al compilatore
che il metodo a cui fa riferimento deve essere
invocato in maniera asincrona, inserendo una
“sospensione” nel flusso di esecuzione, per
riprendere dal metodo successivo nel momento
in cui tale metodo asincrono è terminato.
Nel frattempo, controllo viene restituito al
chiamante del metodo asincrono garantendo
che questo non sia bloccato.
18. Async/Await e i Task
La classe Task è uno strumento con cui
implementare metodi «awaitabili» (l’altro è
l’interfaccia IAsyncOperation)
La parola chiave Await davanti ad una funzione che
ritorna un Task, ne cambia «magicamente» il valore
di ritorno (e il comportamento):
19. Async/Await e i Task
Esempio: metodo DownloadStringTaskAsync
della classe WebClient
Un metodo che restituisce un Task è definito
«Awaitable» e può essere usato in maniera
asincrona anteponendo Await:
21. La «magia» del compilatore
Il compilatore, grazie alle parole chiave
Async e Await, è in grado di:
• Gestire tutti i task eventualmente creati
all’interno di un metodo «Awaitable»;
• Gestire la macchina a stati per il corretto
richiamo degli stessi.
22. La «magia» del compilatore
Il compilatore, dietro le quinte, crea una
macchina a stati i cui stati sono i possibili
flussi tra i diversi metodi «Awaitabili»
richiamati.
Per ogni metodo Async, viene creata una
struttura che implementa l’interfaccia
IAsyncStateMachine deputata alla gestione
della macchina a stati.
23. Async/Await e i thread
L’uso di Async/Await può generare o meno
la creazione di nuovi thread.
Un metodo Async «gira» nel
«synchronization context» corrente.
Solo nel caso di Task.Run avremo l’effettiva
creazione di un thread separato
(sincronizzato dal compilatore).
25. Annullare l’esecuzione di un Async
In alcuni casi può essere necessario
annullare una operazione Async.
Poiché alla base del paradigma Async/Await
c’è il Task, possiamo ricorrere al
CancellationToken per annullare
un’operazione asincrona esattamente come
faremo per un Task.
27. Progress di un Async
Se vogliamo supportare l’aggiornamento
dell’interfaccia grafica, possiamo utilizzare
l’interfaccia IProgress(Of T).
E’ sufficiente prevedere un parametro di tipo
IProgress(Of T) con T il tipo da comunicare
alla UI per l’aggiornamento.
29. Riutilizzare vecchio codice
Se abbiamo del codice «legacy» che dobbiamo
rapidamente riutilizzare in ottica Async,
possiamo far leva sulla classe Task:
Public Function LegacyMethod(i As Integer) As Integer
.
.
End Function
Public Function LegacyMethodAsync(i As Integer) As Task(Of Integer)
Dim task = Task.Run(Function() LegacyMethod(i))
Return task
End Function
30. Riutilizzare vecchio codice
Se possibile è meglio ristrutturare il codice
«legacy» utilizzando internamente metodi
«Awaitable» forniti dal framework anziché
usare il Task a tappeto.
Se si utilizza, ad esempio, il metodo
DownloadString della classe WebClient, è
meglio sostituirlo con il metodo
DownloadStringTaskAsync piuttosto che
incapsulare tutto il nostro metodo in un task.
31. Async/Await e Windows Store
Apps
Tutte le operazioni che, potenzialmente,
possono durare più di 50ms, sono
asincrone!
Il framework per le Windows Store Apps
espone, per queste operazioni, solo ed
esclusivamente i metodi Async!
Ragionate nello stesso modo per le vostre
applicazioni (senza esagerare)!
32. Async/Await e .NET framework 4.0
Possiamo utilizzare il pattern Async/Await anche con
il framework 4.0 utilizzando l’Async Targetting Pack.
Il pack permette di usare Await in VS2012 con le
seguenti versioni di progetto:
• .NET Framework 4.0 (con KB2468871)
• Silverlight 4 e 5
• Windows Phone 7.5
• Portable Class Libraries per le precedenti
piattaforme
35. Riferimenti
Async Targeting Pack per VS2012
http://www.microsoft.com/en-us/download/details.aspx?id=29576
Asynchronous Programming with Async and
Await (C# and Visual Basic)
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Asynchronous programming (Windows Store
apps)
http://msdn.microsoft.com/en-
us/library/windows/apps/hh464924.aspx
Base Class Library (BCL) Blog
http://blogs.msdn.com/b/bclteam/