Condividi tramite


await (Riferimenti per C#)

L'operatore await si applica a un'attività in un metodo asincrono per sospendere l'esecuzione del metodo finché l'attività attesa non viene completata. L'attività rappresenta il lavoro in corso.

Il metodo asincrono in cui viene utilizzato await deve essere modificato dalla parola chiave async. Un metodo di questo tipo, definito utilizzando il modificatore async e contenente in genere una o più espressioni await, viene definito metodo asincrono.

Nota

Le parole chiave await e async introdotte in Visual Studio 2012.Per un'introduzione alla programmazione asincrona, vedere Programmazione asincrona con Async e Await (C# e Visual Basic).

L'attività a cui l'operatore await viene applicato in genere è il valore restituito da una chiamata a un metodo che implementa il modello asincrono basato su attività. Gli esempi includono valori di tipo Task o Task.

Nel codice seguente tramite il metodo GetByteArrayAsync di HttpClient viene restituito un oggetto Task<byte[]>, getContentsTask. L'attività è una promessa di produrre la matrice di byte attuale quando l'attività è completa. L'operatore await viene applicato a getContentsTask per sospendere l'esecuzione in SumPageSizesAsync finché getContentsTask non sia completo. Contemporaneamente, viene restituito il controllo al chiamante di SumPageSizesAsync. Al termine di getContentsTask, l'espressione await restituisce una matrice di byte.

private async Task SumPageSizesAsync()
{
    // To use the HttpClient type in desktop apps, you must include a using directive and add a 
    // reference for the System.Net.Http namespace.
    HttpClient client = new HttpClient();
    // . . .
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;

    // Equivalently, now that you see how it works, you can write the same thing in a single line.
    //byte[] urlContents = await client.GetByteArrayAsync(url);
    // . . .
}

Importante

Per l'esempio completo, vedere Procedura dettagliata: accesso al Web tramite Async e Await (C# e Visual Basic).È possibile scaricare l'esempio da Esempi di codice dello sviluppatore sul sito Web Microsoft.L'esempio è incluso nel progetto AsyncWalkthrough_HttpClient.

Come mostrato nell'esempio precedente, se await viene applicata al risultato di una chiamata al metodo che restituisce Task<TResult>, il tipo dell'espressione await è TResult. Se await viene applicata al risultato di una chiamata al metodo tramite cui viene restituito Task, il tipo dell'espressione await è void. Nell'esempio riportato di seguito vengono illustrate le differenze.

// Keyword await used with a method that returns a Task<TResult>.
TResult result = await AsyncMethodThatReturnsTaskTResult();

// Keyword await used with a method that returns a Task.
await AsyncMethodThatReturnsTask();

Un'espressione await non blocca il thread in cui è in esecuzione. L'operazione comporta invece la registrazione, tramite il compilatore, della parte restante del metodo asincrono come continuazione nell'attività attesa. Il controllo viene restituito al chiamante del metodo asincrono. Quando l'attività viene completata, richiama la relativa continuazione e l'esecuzione del metodo async viene ripresa nel punto dove era stata interrotta.

Un'espressione await può verificarsi solo nel corpo di un metodo che la contiene, di un'espressione lambda o di un metodo anonimo contrassegnato da un modificatore async. Il termine attesa funge da parola chiave solo in tale contesto. In altre situazioni, viene interpretato come identificatore. All'interno del metodo, dell'espressione lambda o del metodo anonimo, un'espressione await non può verificarsi nel corpo di una funzione sincrona, in un'espressione di query, nel blocco catch o finally di un'istruzione di gestione delle eccezioni, nel blocco di un'istruzione lock o in un contesto unsafe.

Eccezioni

Tramite la maggior parte dei metodi asincroni viene restituito un oggetto Task o Task. Le proprietà dell'attività restituita contengono informazioni sul relativo stato e cronologia, come se l'attività è stata completata, se il metodo async ha provocato un'eccezione o è stato annullato e qual è il risultato finale. L'operatore await accede a quelle proprietà.

Se si attende un metodo asincrono tramite cui viene restituita un'attività che comporta un'eccezione, tramite l'operatore await viene rigenerata l'eccezione.

Se si attende un metodo asincrono tramite cui viene restituita un'attività che è stato annullato, tramite l'operatore await viene rigenerata un'eccezione OperationCanceledException.

Una singola attività in uno stato di errore può rispecchiare più eccezioni. Ad esempio, l'attività potrebbe essere il risultato di una chiamata al metodo Task.WhenAll. Quando si attende tale attività, l'operazione di attesa esegue il rethrow di una sola delle eccezioni. Tuttavia, non è possibile prevedere le eccezioni che vengono generate di nuovo.

Per esempi di gestione degli errori in metodi asincroni, vedere try-catch (Riferimenti per C#).

Esempio

Nell'esempio seguente di Windows Form viene illustrato l'utilizzo di await in un metodo async, WaitAsynchronouslyAsync. Contrapporre il comportamento di tale metodo con il comportamento di WaitSynchronously. Senza un operatore await applicato a un'attività, WaitSynchronously viene eseguito in modo sincrono nonostante l'uso del modificatore async nella definizione e in una chiamata a Thread.Sleep nel corpo.

private async void button1_Click(object sender, EventArgs e)
{
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;
}

// 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 Task<string> WaitAsynchronouslyAsync()
{
    await Task.Delay(10000);
    return "Finished";
}

// 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 Task<string> WaitSynchronously()
{
    // Add a using directive for System.Threading.
    Thread.Sleep(10000);
    return "Finished";
}

Vedere anche

Attività

Procedura dettagliata: accesso al Web tramite Async e Await (C# e Visual Basic)

Riferimenti

async (Riferimenti per C#)

Concetti

Programmazione asincrona con Async e Await (C# e Visual Basic)