Condividi tramite


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

È possibile evitare colli di bottiglia delle prestazioni e migliorare la risposta generale dell'applicazione utilizzando la programmazione asincrona.Tuttavia, le tecniche tradizionali per la creazione di applicazioni asincrone possono essere complesse, pertanto difficile scrivere, il debug e gestire.

Visual Studio 2012 introduce un approccio semplificato, di programmazione asincrona, utilizzando il supporto asincrono in .NET Framework 4.5 e in Windows Runtime.Il compilatore esegue il lavoro complessa che lo sviluppatore utilizzato per eseguire e l'applicazione mantiene una struttura logica simile al codice sincrono.Di conseguenza, si ottengono tutti i vantaggi della programmazione asincrona con una frazione di stress.

Di seguito sono elencate le diverse sezioni di questo argomento.

  • Async migliora la risposta
  • I metodi di Async sono più facili da scrivere
  • Ciò che si verifica in un metodo di Async
  • Metodi delle API Async
  • Thread
  • Async e attende
  • Tipi di Ritorno e Parametri
  • Convenzione di denominazione
  • Argomenti correlati
  • Esempio completo
  • Argomenti correlati

In questo argomento viene fornita una panoramica di come e quando utilizzare la programmazione async e vengono forniti collegamenti per supportare gli argomenti contenenti informazioni dettagliate ed esempi.

Async migliora la risposta

Asynchrony è fondamentale per le attività che potenzialmente bloccano, ad esempio quando l'applicazione accede al web.Accesso a una risorsa Web talvolta è lento o posticipata.Se tale attività è bloccata in un processo sincrono, l'intera applicazione deve attendere.In un processo asincrono, l'applicazione può continuare con altro lavoro che non dipende dalla risorsa Web potenzialmente finché il blocco dell'attività.

Nella tabella riportata in aree tipici in cui la programmazione asincrona migliora la risposta.Le API elencati da .NET Framework 4.5 e Windows Runtime contengono metodi che supportano la programmazione async.

Campo di applicazione

API di supporto che contengono metodi async

Accesso al web

HttpClient, SyndicationClient

Utilizzo dei file

StorageFile, StreamWriter, StreamReader, XmlReader

Utilizzo delle immagini

MediaCaptureBitmapEncoder, BitmapDecoder

Programmazione di WCF

Sincrono e operazioni asincrone

Utilizzo di socket

Socket

Asynchrony prova particolarmente importante per le applicazioni che accedono al thread UI poiché qualsiasi attività l'Interfaccia utente correlata in genere condivide un thread.Se il processo bloccato in un'applicazione sincrona, tutti bloccati.L'applicazione non risponde e potrebbe concludere che ha avuto esito negativo quando invece è in attesa solo.

Quando si utilizzano i metodi asincroni, l'applicazione continua a rispondere all'interfaccia utente.È possibile ridimensionare o ridurre a iconavi una finestra, ad esempio o, può chiudere l'applicazione se non si desidera attendere per completare.

All'approccio basato async aggiunge l'equivalente di una trasmissione automatica all'elenco di opzioni da cui è possibile scegliere quando si progetta operazioni asincrone.Ovvero si ottengono tutti i vantaggi della programmazione asincrona tradizionale ma con molto meno sforzo dallo sviluppatore.

I metodi di Async sono più facili da scrivere

Le parole chiave di Attendere e di Async in Visual Basic e le parole chiave di attendere e di async in c sono fondamentale di programmazione async.Utilizzando queste due parole chiave, è possibile utilizzare le risorse di .NET Framework o in Windows Runtime per creare un metodo asincrono quasi facilmente come creare un metodo sincrono.I metodi asincroni definite mediante il async e si attendono vengono definiti i metodi async.

Nell'esempio seguente viene illustrato un metodo async.Quasi tutti nel codice dovrebbe risultare completamente noto all'utente.I commenti richiamano le funzionalità che viene aggiunto per creare il asynchrony.

È possibile trovare il file di esempio completo alla fine di questo argomento e è possibile scaricare l'esempio da Esempio di Async: L'esempio "di programmazione asincrona con Async e attende".

' Three things to note in the signature:
'  - The method has an Async modifier. 
'  - The return type is Task or Task(Of T). (See "Return Types" section.)
'    Here, it is Task(Of Integer) because the return statement returns an integer.
'  - The method name ends in "Async."
Async Function AccessTheWebAsync() As Task(Of Integer)

    ' You need to add a reference to System.Net.Http to declare client.
    Dim client As HttpClient = New HttpClient()

    ' GetStringAsync returns a Task(Of String). That means that when you await the
    ' task you'll get a string (urlContents).
    Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


    ' You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork()

    ' The Await operator suspends AccessTheWebAsync.
    '  - AccessTheWebAsync can't continue until getStringTask is complete.
    '  - Meanwhile, control returns to the caller of AccessTheWebAsync.
    '  - Control resumes here when getStringTask is complete. 
    '  - The Await operator then retrieves the string result from getStringTask.
    Dim urlContents As String = Await getStringTask

    ' The return statement specifies an integer result.
    ' Any methods that are awaiting AccessTheWebAsync retrieve the length value.
    Return urlContents.Length
End Function
// Three things to note in the signature:
//  - The method has an async modifier. 
//  - The return type is Task or Task<T>. (See "Return Types" section.)
//    Here, it is Task<int> because the return statement returns an integer.
//  - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync.
    //  - AccessTheWebAsync can't continue until getStringTask is complete.
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync.
    //  - Control resumes here when getStringTask is complete. 
    //  - The await operator then retrieves the string result from getStringTask.
    string urlContents = await getStringTask;

    // The return statement specifies an integer result.
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value.
    return urlContents.Length;
}

Se AccessTheWebAsync non ha alcun modo che possa eseguire tra chiamare GetStringAsync e attendere il completamento, è possibile semplificare il codice chiamando e attesa nell'istruzione singolo.

Dim urlContents As String = Await client.GetStringAsync()
string urlContents = await client.GetStringAsync();

Le seguenti caratteristiche riepilogano ciò che rende esempio precedente un metodo async.

  • La firma del metodo include un modificatore di async o di Async.

  • Il nome di un metodo async, per convenzione, termina con un suffisso "Async".

  • Il tipo restituito è uno dei seguenti tipi:

    • Task<TResult> se il metodo ha un'istruzione return in cui l'operando è di tipo TResult.

    • Task se il metodo non ha istruzione return o contiene un'istruzione return senza l'operando.

    • In void (in Visual Basic) se si scrive un gestore eventi async.

    Per ulteriori informazioni, vedere più avanti "tipi restituiti e i parametri" in questo argomento.

  • Il metodo in genere include almeno uno attesa l'espressione, che contrassegna un punto in cui il metodo non può continuare fino a quando l'operazione asincrona attesa non sia completata.Contemporaneamente, il metodo viene sospeso e restituisce il controllo al chiamante del metodo.La sezione successiva di questo argomento viene illustrato quello che si verifica al punto di sospensione.

Nei metodi async, utilizzare le parole chiave e i tipi forniti per indicare l'operazione che si desidera eseguire e il compilatore esegue il resto, inclusi tenere traccia di quali deve verificarsi quando il controllo viene restituito a un punto di attesa in un metodo sospeso.Alcuni processi di routine, ad esempio cicli e gestione delle eccezioni, possono essere difficili da gestire nel codice asincrono tradizionale.In un metodo async, scrivere questi elementi come in una soluzione sincrona e il problema viene risolto.

Per ulteriori informazioni su asynchrony nelle versioni precedenti di.NET Framework, vedere Task Parallel Library e programmazione asincrona .NET tradizionale.

Ciò che si verifica in un metodo di Async

La maggior parte degli elementi importante comprendere nella programmazione asincrona è illustrato il flusso di controllo si sposta dal metodo al metodo.Nel diagramma seguente vengono descritti con il processo.

Tracciare un programma asincrono

I numeri nel diagramma corrispondono ai passaggi seguenti.

  1. Un gestore eventi chiama e attende il metodo async di AccessTheWebAsync.

  2. AccessTheWebAsync crea un'istanza di HttpClient e chiama GetStringAsync metodo asincrono per scaricare il contenuto di un sito Web come stringa.

  3. Si verifica qualcosa in GetStringAsync che sospenda lo stato di avanzamento.Forse deve attendere che un sito Web per scaricare o un'altra attività di blocco.Per evitare di bloccare le risorse, controllo al chiamante, AccessTheWebAsyncdi valori di GetStringAsync.

    GetStringAsync restituisce Task<TResult> dove TResult è una stringa e AccessTheWebAsync assegnata l'attività alla variabile di getStringTask.L'attività rappresenta il processo corrente per la chiamata a GetStringAsync, con un impegno per produrre un valore effettivo stringa quando il lavoro è stato completato.

  4. Poiché getStringTask non è stato ancora attesa, AccessTheWebAsync può continuare con altro lavoro che non dipende dal risultato finale da GetStringAsync.Tale lavoro è rappresentato da una chiamata al metodo sincrono DoIndependentWork.

  5. DoIndependentWork è un metodo sincrono che esegue il lavoro e restituisce al chiamante.

  6. AccessTheWebAsync ha esaurito il lavoro che può essere a meno di un risultato da getStringTask.dopoAccessTheWebAsync desideri calcolare e restituire la lunghezza della stringa scaricata, ma il metodo non potrà calcolare il valore finché il metodo non sia la stringa.

    Pertanto, AccessTheWebAsync utilizza un operatore di attesa per sospendere lo stato di avanzamento e rendere il controllo al metodo che ha chiamato AccessTheWebAsync.AccessTheWebAsync restituisce Task(Of Integer) o Task<int> al chiamante.L'attività rappresenta un suggerimento per produrre un risultato intero che rappresenta la lunghezza della stringa scaricata.

    [!NOTA]

    Se GetStringAsync (e quindi getStringTask) non è stata completata prima che AccessTheWebAsync lo attendere controlli, resta in AccessTheWebAsync.La spesa di sospensione e quindi di tornare a AccessTheWebAsync sarebbe sprecata se il processo asincrono denominato ()getStringTaskgià completato e AccessTheWebSync non deve attendere il risultato finale.

    Nel chiamante (il gestore eventi in questo esempio, il processo viene ripetuto.Il chiamante può eseguire altro lavoro che non dipende dal risultato di AccessTheWebAsync prima di iniziare ad attendere che tale risultato, o il chiamante può attendere immediatamente.Quando il gestore eventi raggiunge un'espressione di attesa, nell'applicazione il completamento di GetStringAsync.Il gestore eventi è in attesa AccessTheWebAsynce AccessTheWebAsync è in attesa GetStringAsync.

  7. GetStringAsync completa e produce un risultato della stringa.Il risultato della stringa non viene restituito dalla chiamata a GetStringAsync nel modo previsto.Si tenga presente che il metodo ha già restituito un'attività al passaggio 3.) il contrario, il risultato della stringa viene archiviato nell'attività che rappresenta il completamento del metodo, getStringTask.L'operatore di attesa recupera il risultato di getStringTask.L'istruzione di assegnazione assegna il risultato a urlContentsrecuperato.

  8. Quando AccessTheWebAsync è il risultato della stringa, il metodo di calcolare la lunghezza della stringa.Quindi il lavoro di AccessTheWebAsync è completo e il gestore eventi in attesa può riattivare.Nell'esempio completo alla fine dell'argomento, è possibile verificare che il gestore eventi recupera e viene visualizzato il valore di output di lunghezza.

Se non si ha esperienza di programmazione asincrona, richiedere un minuto per considerare la differenza tra il comportamento sincrono e asincrono.Restituisce sincroni di un metodo quando il lavoro è pieno (passaggio 5), ma un metodo async restituisce un valore di attività quando il lavoro viene sospeso (passaggi 3 e 6).Quando il metodo async eventualmente completa le operazioni, l'attività viene contrassegnata come terminata e il risultato, se presente, viene archiviato nell'attività.

Per ulteriori informazioni sul flusso di controllo, vedere Flusso di controllo in programmi asincroni (C# e Visual Basic).

Metodi delle API Async

È domandarti dove cercare i metodi come GetStringAsync che supportano la programmazione async.Il .NET Framework 4.5 contiene molti membri che utilizzano async e await.È possibile riconoscere questi membri dal suffisso "Async" associato dal nome del membro e dal tipo restituito Task o Task<TResult>.Ad esempio, la classe di System.IO.Stream contiene metodi come CopyToAsync, ReadAsynce WriteAsync accanto ai metodi sincroni CopyTo, Reade Write.

Windows Runtime contiene inoltre numerosi metodi che è possibile utilizzare con async e attendere nelle applicazioni di Windows Store.Per più metodi di esempio e informazioni, vedere Guida rapida: utilizzando l'operatore di attesa per la programmazione asincrona, Programmazione asincrona (applicazioni dell'archivio di Windows)e WhenAny: bridging tra .NET Framework e Windows Runtime (C# e Visual Basic).

Thread

I metodi di Async vengono considerati operazioni non bloccanti.Un'espressione await in un metodo async non blocca il thread corrente quando l'attività attesa è in esecuzione.Al contrario, l'espressione si registra il resto del metodo come continuazione e restituisce il controllo al chiamante del metodo asincrono.

Il async e attende le parole chiave non determina thread aggiuntivi a essere creato.I metodi asincroni non richiedono multithreading perché non viene eseguito un metodo asincrono nel relativo thread.Il metodo viene eseguito nel contesto di sincronizzazione e il tempo corrente del thread viene utilizzato solo se il metodo è attivo.È possibile utilizzare Task.Run di lavoro associato alla CPU spostarsi su un thread in background, ma un thread in background non consente un processo che è in attesa dei risultati diventi disponibile.

All'approccio basato async per la programmazione asincrona è preferibile agli approcci esistenti in quasi ogni caso.In particolare, questo approccio risulta più efficiente di BackgroundWorker per le operazioni IO- associate perché il codice è più semplice e non è necessario evitare da race condition.Combinazione con Task.Run, la programmazione asincrono viene migliorata di BackgroundWorker per le operazioni associate alla CPU perché la programmazione async separa i dettagli di coordinamento di eseguire il codice dal lavoro che Task.Run trasferisce a threadpool.

Async e attende

Se si specifica che un metodo è un metodo async utilizzando un modificatore di async o di Async, attivare le seguenti due funzionalità.

  • Il metodo contrassegnato async può utilizzare Attendere o attendere per definire i punti di sospensione.L'operatore di attesa indica al compilatore che il metodo async non può continuare l'esperienza che punta al processo asincrono attesa non sia completo.Contemporaneamente, restituisce il controllo al chiamante del metodo async.

    La sospensione di un metodo async a un'espressione di attesa non costituisce l'uscita dal metodo e i blocchi di finally non funzionano.

  • Il metodo è contrassegnato stesso async essere atteso con metodi che lo chiama.

Un metodo async in genere contiene uno o più occorrenze di un operatore di attesa, mentre l'assenza di attesa espressioni non provoca un errore del compilatore.Se un metodo async non utilizza un operatore di attesa per contrassegnare un punto di sospensione, il metodo viene eseguito come un metodo sincrono affermativo, nonostante il modificatore async.I problemi del compilatore comportano la generazione di un avviso da parte dei metodi.

Async, async, Awaite await rappresentano parole chiave contestuali.Per ulteriori informazioni ed esempi, vedere i seguenti argomenti:

Tipi di Ritorno e Parametri

In .NET Framework che programma, un metodo async in genere restituisce Task o Task<TResult>.In un metodo async, un operatore di attesa viene applicato a un'attività restituita da una chiamata a un altro metodo async.

Specificare Task<TResult> come tipo restituito se il metodo contiene un'istruzione Return (Visual Basic) o return (C#) che specifica un operando di tipo TResult.

Utilizzare Task come tipo restituito se il metodo non ha istruzione return o contiene un'istruzione return che non restituisce un operando.

Di seguito viene illustrato come dichiarare e chiamare un metodo che restituisce Task<TResult> o Task.

' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)

    Dim hours As Integer
    ' . . .
    ' Return statement specifies an integer result.
    Return hours
End Function

' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()


' Signature specifies Task
Async Function Task_MethodAsync() As Task

    ' . . .
    ' The method has no return statement.
End Function

' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()
// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // Return statement specifies an integer result.
    return hours;
}

// Calls to TaskOfTResult_MethodAsync
Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
int intResult = await returnedTaskTResult;
// or, in a single statement
int intResult = await TaskOfTResult_MethodAsync();


// Signature specifies Task
async Task Task_MethodAsync()
{
    // . . .
    // The method has no return statement.  
}

// Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync();
await returnedTask;
// or, in a single statement
await Task_MethodAsync();

Ogni attività restituita rappresenta il lavoro in corso.Un'attività include le informazioni sullo stato del processo asincrono e, infine, il risultato finale del processo o l'eccezione che genera di processo in caso contrario.

Un metodo async può essere un metodo di Sub (Visual Basic) o avere un tipo restituito di void (c).Questo tipo restituito viene utilizzato principalmente per definire i gestori eventi, in cui un tipo restituito di void è obbligatorio.I gestori eventi di Asincrona spesso funge da punto di partenza per i programmi async.

Un metodo async che è una routine Sub o con un tipo restituito void non può essere sospeso e il chiamante di un metodo void non può rilevare le eccezioni che il metodo genera.

Un metodo async non può dichiarare i parametri ByRef in Visual Basic o in ref o parametri out in C#, ma il metodo può chiamare i metodi che presentano tali parametri.

Per ulteriori informazioni ed esempi, vedere Tipi restituiti asincroni (C# e Visual Basic).Per ulteriori informazioni su come intercettare eccezioni nei metodi async, vedere try-catch (Riferimenti per C#) o Istruzione Try...Catch...Finally (Visual Basic).

Le API asincroni nella programmazione di Windows Runtime hanno uno dei seguenti tipi restituiti, simili alle attività:

Per ulteriori informazioni e un esempio, vedere Guida rapida: utilizzando l'operatore di attesa per la programmazione asincrona.

Convenzione di denominazione

Per convenzione, aggiunte "Async" ai nomi dei metodi che presentano un modificatore di async o di Async.

È possibile ignorare la convenzione dove un evento, una classe base, o un contratto dell'interfaccia suggeriscono un nome diverso.Ad esempio, non è necessario rinominare i gestori di eventi comuni, come Button1_Click.

Argomenti correlati

Titolo

Descrizione

Esempio

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

Viene illustrato come convertire una soluzione sincrona WPF a una soluzione asincrona WPF.L'applicazione scarica una serie di siti Web.

Esempio di Async: Accesso alla procedura dettagliata Web (c e Visual Basic)

Procedura: estendere la procedura dettagliata tramite Task.WhenAll (C# e Visual Basic)

Aggiungere Task.WhenAll alla procedura dettagliata precedente.L'utilizzo di WhenAll avvia tutti i download contemporaneamente.

Procedura: effettuare più richieste Web in parallelo (C# e Visual Basic)

Viene illustrato come avviare contemporaneamente diverse attività.

Esempio di Async: Effettua richieste Web in parallelo (c e Visual Basic)

Tipi restituiti asincroni (C# e Visual Basic)

Vengono illustrati i tipi che i metodi async possono restituire e viene spiegato quando ogni tipo appropriato.

Flusso di controllo in programmi asincroni (C# e Visual Basic)

Le analisi il flusso di controllo con una successione di attesa in dettaglio le espressioni in un programma asincrono.

Esempio di Async: Flusso di controllo programmi di Async (c e Visual Basic)

Ottimizzazione dell'applicazione Async (C# e Visual Basic)

Viene illustrato come aggiungere la seguente funzionalità alla soluzione async:

Esempio di Async: Ottimizzando l'applicazione (c e Visual Basic)

Gestione della reentrancy nelle applicazioni asincrone (C# e Visual Basic)

Viene illustrato come gestire i casi in cui un'operazione asincrona attiva viene riavviata in esecuzione.

WhenAny: bridging tra .NET Framework e Windows Runtime (C# e Visual Basic)

Viene illustrato come integrare un ponte tra l'attività in .NET Framework e lo IAsyncOperations in Windows Runtime in modo da poter utilizzare la WhenAny con un metodo di Windows Runtime.

Esempio di Async: Gettando un ponte tra.NET e il runtime di Windows (AsTask e WhenAny)

Annullamento: bridging tra .NET Framework e Windows Runtime (C# e Visual Basic)

Viene illustrato come integrare un ponte tra l'attività in .NET Framework e lo IAsyncOperations in Windows Runtime in modo da poter utilizzare CancellationTokenSource con un metodo di Windows Runtime.

Esempio di Async: Gettando un ponte tra.NET e il runtime di Windows (& AsTask annullamento)

Utilizzo della funzionalità Async per l'accesso ai file (C# e Visual Basic)

Vengono elencati e illustrati i vantaggi del async e attende per accedere ai file.

Procedura dettagliata: utilizzo del debugger con metodi Async

Viene illustrato il flusso di controllo in un'istruzione di await e viene illustrato il comportamento di Esegui istruzione, Esegui istruzione/routinee controlli Esci da istruzione/routine nei metodi async.

Modello asincrono basato su attività (TAP)

Viene descritto un nuovo modello asincronico in .NET Framework.Il modello basato sui tipi Task<TResult> e Task.

Guida rapida: API asincroni chiamante in c o in Visual Basic

Viene illustrato come utilizzare async e attendere in un'applicazione di Windows Store.

Programmazione asincrona (applicazioni dell'archivio di Windows)

Vengono forniti cenni preliminari sulla programmazione asincrona in Windows Runtime.

Visualizzazione di Async sulla copertina 9

Vengono forniti collegamenti a una serie di visualizzare sulla programmazione async.

Esempio completo

Il codice seguente rappresenta il file MainWindow.xaml.cs o MainWindow.xaml.vb dall'applicazione Windows Presentation Foundation (WPF) che questo argomento viene illustrato.È possibile scaricare l'esempio da Esempio di Async: L'esempio "di programmazione asincrona con Async e attende".

' Add an Imports statement and a reference for System.Net.Http
Imports System.Net.Http

Class MainWindow

    ' Mark the event handler with async so you can use Await in it.
    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)

        ' Call and await separately.
        'Task<int> getLengthTask = AccessTheWebAsync();
        '' You can do independent work here.
        'int contentLength = await getLengthTask;

        Dim contentLength As Integer = Await AccessTheWebAsync()

        ResultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
    End Sub


    ' Three things to note in the signature:
    '  - The method has an Async modifier. 
    '  - The return type is Task or Task(Of T). (See "Return Types" section.)
    '    Here, it is Task(Of Integer) because the return statement returns an integer.
    '  - The method name ends in "Async."
    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' You need to add a reference to System.Net.Http to declare client.
        Dim client As HttpClient = New HttpClient()

        ' GetStringAsync returns a Task(Of String). That means that when you await the
        ' task you'll get a string (urlContents).
        Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


        ' You can do work here that doesn't rely on the string from GetStringAsync.
        DoIndependentWork()

        ' The Await operator suspends AccessTheWebAsync.
        '  - AccessTheWebAsync can't continue until getStringTask is complete.
        '  - Meanwhile, control returns to the caller of AccessTheWebAsync.
        '  - Control resumes here when getStringTask is complete. 
        '  - The Await operator then retrieves the string result from getStringTask.
        Dim urlContents As String = Await getStringTask

        ' The return statement specifies an integer result.
        ' Any methods that are awaiting AccessTheWebAsync retrieve the length value.
        Return urlContents.Length
    End Function


    Sub DoIndependentWork()
        ResultsTextBox.Text &= "Working . . . . . . ." & vbCrLf
    End Sub
End Class

' Sample Output:

' Working . . . . . . .

' Length of the downloaded string: 41763.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http;
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it.
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately.
            //Task<int> getLengthTask = AccessTheWebAsync();
            //// You can do independent work here.
            //int contentLength = await getLengthTask;

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature:
        //  - The method has an async modifier. 
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer.
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            HttpClient client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

            // You can do work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork();

            // The await operator suspends AccessTheWebAsync.
            //  - AccessTheWebAsync can't continue until getStringTask is complete.
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync.
            //  - Control resumes here when getStringTask is complete. 
            //  - The await operator then retrieves the string result from getStringTask.
            string urlContents = await getStringTask;

            // The return statement specifies an integer result.
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value.
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output:

// Working . . . . . . .

// Length of the downloaded string: 41564.

Vedere anche

Riferimenti

async (Riferimenti per C#)

await (Riferimenti per C#)

Opertore Await (Visual Basic)

Async (Visual Basic)