Condividi tramite


Operatore Await (Visual Basic)

L'operatore Await viene applicato a un operando in un metodo asincrono o in un'espressione lambda per sospendere l'esecuzione del metodo fino al completamento dell'attività attesa. L'attività rappresenta il lavoro attualmente in fase di esecuzione.

Il metodo in cui Await viene utilizzato deve avere un modificatore asincrono . Tale metodo, definito usando il Async modificatore e in genere contenente una o più Await espressioni, viene definito metodo asincrono.

Annotazioni

Le Async parole chiave e Await sono state introdotte in Visual Studio 2012. Per un'introduzione alla programmazione asincrona, vedere Programmazione asincrona con Async e Await.

In genere, l'attività a cui si applica l'operatore Await è il valore restituito da una chiamata a un metodo che implementa il modello asincronoTask-Based, ovvero un oggetto Task o .Task<TResult>

Nel codice seguente il HttpClient metodo restituisce getContentsTask, un oggetto Task(Of Byte())GetByteArrayAsync . L'attività è una promessa per produrre la matrice di byte effettiva al termine dell'operazione. L'operatore Await viene applicato a getContentsTask per sospendere l'esecuzione fino SumPageSizesAsync al getContentsTask completamento. Nel frattempo, il controllo viene restituito al chiamante di SumPageSizesAsync. Al getContentsTask termine, l'espressione Await restituisce una matrice di byte.

Private Async Function SumPageSizesAsync() As Task

    ' To use the HttpClient type in desktop apps, you must include a using directive and add a
    ' reference for the System.Net.Http namespace.
    Dim client As HttpClient = New HttpClient()
    ' . . .
    Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
    Dim urlContents As Byte() = Await getContentsTask

    ' Equivalently, now that you see how it works, you can write the same thing in a single line.
    'Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    ' . . .
End Function

Importante

Per l'esempio completo, vedere Procedura dettagliata: Accesso al Web tramite Async e Await. È possibile scaricare l'esempio dal browser di esempio .NET. Il codice di esempio si trova nel progetto SerialAsyncExample.

Se Await viene applicato al risultato di una chiamata al metodo che restituisce un Task(Of TResult)oggetto , il tipo dell'espressione Await è TResult. Se Await viene applicato al risultato di una chiamata al metodo che restituisce un Taskoggetto , l'espressione Await non restituisce un valore. Nell'esempio che segue viene illustrata la differenza.

' Await used with a method that returns a Task(Of TResult).
Dim result As TResult = Await AsyncMethodThatReturnsTaskTResult()

' Await used with a method that returns a Task.
Await AsyncMethodThatReturnsTask()

Un'espressione Await o un'istruzione non blocca il thread su cui è in esecuzione. Fa invece in modo che il compilatore scriva il resto del metodo asincrono, dopo l'espressione Await , come continuazione sull'attività attesa. Il controllo torna quindi al chiamante del metodo asincrono. Al termine dell'attività, richiama la continuazione e l'esecuzione del metodo asincrono riprende da dove è stata interrotta.

Un'espressione Await può verificarsi solo nel corpo di un metodo di inclusione immediata o di un'espressione lambda contrassegnata da un Async modificatore. Il termine Await funge da parola chiave solo in tale contesto. Altrove, viene interpretato come identificatore. All'interno del metodo o dell'espressione Async lambda, un'espressione Await non può verificarsi in un'espressione Catch di query, nel blocco o Finally di un oggetto Try... Prendere... Infine, nell'espressione della variabile di controllo del ciclo di un For ciclo o For Each nel corpo di un'istruzione SyncLock .

Eccezioni

La maggior parte dei metodi asincroni restituisce un Task oggetto o Task<TResult>. Le proprietà dell'attività restituita contengono informazioni sullo stato e sulla cronologia, ad esempio se l'attività è stata completata, se il metodo asincrono ha causato un'eccezione o è stato annullato e qual è il risultato finale. L'operatore Await accede a tali proprietà.

Se si attende un metodo asincrono che restituisce un'attività che causa un'eccezione, l'operatore Await genera nuovamente l'eccezione.

Se si attende un metodo asincrono che restituisce un'attività annullata, l'operatore Await rigenera un oggetto OperationCanceledException.

Una singola attività che si trova in uno stato di errore può riflettere più eccezioni. Ad esempio, l'attività può essere il risultato di una chiamata a Task.WhenAll. Quando si attende un'attività di questo tipo, l'operazione await rigenera solo una delle eccezioni. Tuttavia, non è possibile stimare quale delle eccezioni viene rigenerata.

Per esempi di gestione degli errori nei metodi asincroni, vedere Try... Prendere... Istruzione Finally.

Esempio

Nell'esempio di Windows Form seguente viene illustrato l'uso di Await in un metodo asincrono, WaitAsynchronouslyAsync. Confrontare il comportamento di tale metodo con il comportamento di WaitSynchronously. Senza un Await operatore, WaitSynchronously viene eseguito in modo sincrono nonostante l'uso del Async modificatore nella relativa definizione e una chiamata a Thread.Sleep nel corpo.

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' Call the method that runs asynchronously.
    Dim result As String = Await WaitAsynchronouslyAsync()

    ' Call the method that runs synchronously.
    'Dim result As String = Await WaitSynchronously()

    ' Display the result.
    TextBox1.Text &= result
End Sub

' The following method runs asynchronously. The UI thread is not
' blocked during the delay. You can move or resize the Form1 window
' while Task.Delay is running.
Public Async Function WaitAsynchronouslyAsync() As Task(Of String)
    Await Task.Delay(10000)
    Return "Finished"
End Function

' The following method runs synchronously, despite the use of Async.
' You cannot move or resize the Form1 window while Thread.Sleep
' is running because the UI thread is blocked.
Public Async Function WaitSynchronously() As Task(Of String)
    ' Import System.Threading for the Sleep method.
    Thread.Sleep(10000)
    Return "Finished"
End Function

Vedere anche