Programación asincrónica con Async y Await (C# y Visual Basic)

Puede evitar cuellos de botella de rendimiento y mejorar la capacidad total de la aplicación mediante la programación asincrónica.Sin embargo, las técnicas tradicionales para escribir aplicaciones asincrónicas pueden resultar complicada, lo que difícil escribir, depurar, y mantener.

Visual Studio 2012 presenta un enfoque simplificado, la programación async, que aprovecha la compatibilidad asincrónica en .NET Framework 4.5 y Windows en tiempo de ejecución.El compilador realiza el trabajo difícil que el desarrollador utilizado para hacer, y la aplicación conserva una estructura lógica similar a código sincrónico.Como resultado, se obtiene todas las ventajas de la programación asincrónica con una parte del esfuerzo.

Este tema contiene las secciones siguientes.

  • Async mejora capacidad
  • Métodos Easier Async a escribir
  • Lo que sucede en un método Async
  • Métodos de la API Async
  • Subprocesos
  • Async y Await
  • Tipos de retorno y parámetros
  • Convención de nomenclatura
  • Temas relacionados
  • Ejemplo completo
  • Temas relacionados

Este tema proporciona información general sobre cuándo y cómo utilizar la programación async e incluye vínculos para admitir temas que contienen detalles y ejemplos.

Async mejora capacidad

Asynchrony es esencial para las actividades que potencialmente bloquean, por ejemplo cuando la aplicación tiene acceso al web.Acceso a un recurso web a veces es lento o retrasada.Si esta actividad está bloqueada dentro de un proceso sincrónico, la aplicación completa debe esperar.En un proceso asincrónico, la aplicación puede continuar con otro trabajo que no depende del recurso web hasta potencialmente bloquear tarea finaliza.

La tabla siguiente se muestran las áreas típicas donde la programación asincrónica mejora su capacidad de respuesta.Las API mencionado de .NET Framework 4.5 y Windows en tiempo de ejecución contienen métodos que programación admiten async.

Área de aplicación

Compatibilidad de API que contiene métodos async

Acceso web

HttpClient, SyndicationClient

Trabajar con archivos

StorageFile, StreamWriter, StreamReader, XmlReader

Trabajar con imágenes

MediaCaptureBitmapEncoder, BitmapDecoder

Programación de WCF

Sincrónico y operaciones asincrónicas

Trabajar con sockets

Socket

Asynchrony prueba especialmente valioso para aplicaciones que tienen acceso al subproceso de la interfaz de usuario porque toda la actividad Interfaz de usuario- relacionada comparte normalmente un subproceso.Si cualquier proceso bloqueado en una aplicación sincrónica, todos bloqueados.La aplicación deja de responder, y puede que termine con errores cuando en su lugar simplemente está esperando.

Cuando utilice métodos asincrónicos, la aplicación continúa respondiendo a la interfaz de usuario.Puede cambiar el tamaño o minimizar una ventana, por ejemplo, o puede cerrar la aplicación si no desea esperar a que finalice.

El enfoque async- basado agrega el equivalente de una transmisión automática a la lista de opciones entre las que puede elegir al diseñar operaciones asincrónicas.Es decir, obtiene todas las ventajas de la programación asincrónica tradicional pero con mucha menos esfuerzo de desarrollador.

Métodos Easier Async a escribir

Las palabras clave de Async y de Espera en Visual Basic y las palabras clave de async y de espera en C# son el núcleo de programación async.Con esas dos palabras clave, puede utilizar los recursos en .NET Framework o Windows en tiempo de ejecución para crear un método asincrónico casi tan fácilmente como crea un método sincrónico.Los métodos asincrónicos que se define utilizando async y espera se denominan métodos async.

El ejemplo siguiente se muestra un método async.Casi todo el código debe ser completamente familiar.Los comentarios informan sobre las características que se agrega para crear el asynchrony.

Puede encontrar el archivo de ejemplo completo al final de este tema, y puede descargar el ejemplo de Ejemplo Async: Ejemplo de “programación asincrónica con Async y Await”.

' 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;
}

Si AccessTheWebAsync no tiene trabajo que pueda hacer entre llamar GetStringAsync y aguardar su realización, puede simplificar el código llamando a y esperando en una sola instrucción siguiente.

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

Las siguientes características resumen qué hace que el ejemplo anterior un método async.

  • La firma del método incluye un modificador de Async o de async.

  • El nombre de un método async, por convención, finaliza con un sufijo “Async”.

  • El tipo de valor devuelto es uno de los tipos siguientes:

    • Task<TResult> si el método tiene una instrucción return en la que el operando tiene el tipo TResult.

    • Task si el método no tiene ninguna instrucción return ni tiene una instrucción return sin operando.

    • Void ( Sub en Visual Basic) si está escribiendo un controlador de eventos async.

    Para obtener más información, vea “tipos de valor devuelto y los parámetros” más adelante en este tema.

  • El método normalmente incluye al menos uno espera la expresión, que marca un punto en el que el método no puede continuar hasta que se completa la operación asincrónica aguardada.Mientras tanto, se suspende el método, y el control vuelve al llamador del método.La sección siguiente de este tema muestra lo que sucede en el punto de suspensión.

En métodos async, se utilizan las palabras clave y los tipos proporcionados para indicar lo que desea hacer, y el compilador realiza el resto, incluido el seguimiento de qué debe ocurrir cuando el control vuelve a un punto de aguardar en un método suspendido.Algunos procesos de la rutina, como bucles y control de excepciones, pueden resultar difíciles de administrar en código asincrónico tradicional.En un método async, se pueden escribir estos elementos como se haría en una solución sincrónica y se resuelve este problema.

Para obtener más información sobre asynchrony en versiones anteriores de.NET Framework, vea TPL y la programación asincrónica tradicional de .NET.

Lo que sucede en un método Async

Lo más importante a entender en la programación asincrónica es cómo el flujo de control se desplaza del método.El diagrama siguiente le guía en el proceso.

Seguimiento de un programa asincrónico

Los números en el diagrama se corresponden con los pasos siguientes.

  1. Un controlador de eventos llama a y espera el método async de AccessTheWebAsync.

  2. AccessTheWebAsync crea una instancia de HttpClient y llama al método asincrónico de GetStringAsync para descargar el contenido de un sitio Web como una cadena.

  3. Sucede algo en GetStringAsync que suspende el progreso.Quizás debe esperar un sitio Web para descargar o alguna otra actividad de bloqueo.Para evitar que los recursos, GetStringAsync hace que el control al llamador, AccessTheWebAsync.

    GetStringAsync devuelve Task<TResult> donde es una cadena TResult, y las asignaciones de AccessTheWebAsync la tarea a la variable de getStringTask.La tarea representa el proceso actual para la llamada a GetStringAsync, con el compromiso de generar un valor de cadena real cuando se completa el trabajo.

  4. Dado que getStringTask no se ha aguardado todavía, AccessTheWebAsync puede continuar con otro trabajo que no depende del resultado final de GetStringAsync.Ese trabajo se representa mediante una llamada al método sincrónico DoIndependentWork.

  5. DoIndependentWork es un método sincrónico que hace el trabajo y vuelve al llamador.

  6. AccessTheWebAsync ha ejecutado sin trabajo que puede realizar sin un resultado de getStringTask.AccessTheWebAsync después desea calcular y devolver la longitud de la cadena descargado, pero el método no puede calcular ese valor hasta que el método tiene la cadena.

    Por consiguiente, AccessTheWebAsync utiliza un operador de aguardar para suspender el progreso y producir el control al método que llamó AccessTheWebAsync.AccessTheWebAsync devuelve Task(Of Integer) o Task<int> al llamador.La tarea representa una sugerencia de generar un resultado entero que es la longitud de la cadena descargado.

    [!NOTA]

    Si se completa GetStringAsync (y por consiguiente getStringTask) antes de que AccessTheWebAsync lo espera, permanece el control en AccessTheWebAsync.El costo de suspensión y después de volver a AccessTheWebAsync se perderán si el proceso denominado asincrónico (getStringTask) ya se ha completado y AccessTheWebSync no debe esperar el resultado final.

    Dentro del llamador (el controlador de eventos en este ejemplo), se repite el proceso.El llamador puede hacer otro trabajo que no depende del resultado de AccessTheWebAsync antes de aguardar ese resultado, o es posible que el llamador aguardar inmediatamente.Cuando el controlador de eventos alcanza una expresión de aguardar, la aplicación se centra en la finalización de GetStringAsync.El controlador de eventos está esperando AccessTheWebAsync, y AccessTheWebAsync está esperando GetStringAsync.

  7. GetStringAsync completa y genera un resultado de la cadena.El resultado de la cadena no es devuelto por la llamada a GetStringAsync de la manera que cabría esperar.Recuerde que el método devuelve ya una tarea en el paso 3). Instead, la cadena se almacena en la tarea que representa el método, getStringTask.El operador aguardar recupera el resultado de getStringTask.La instrucción de asignación asigna el resultado recuperado a urlContents.

  8. Cuando AccessTheWebAsync tiene el resultado de la cadena, el método puede calcular la longitud de la cadena.El trabajo de AccessTheWebAsync también se completa, y el controlador de eventos que espera puede reanudar.En el ejemplo completo en el final de este tema, puede comprobar que el controlador de eventos recupera e imprime el valor de resultado de longitud.

Si no está familiarizado con la programación asincrónica, reserve un minuto para ver la diferencia entre el comportamiento sincrónico y asincrónico.Un método sincrónico devuelve cuando se completa el trabajo (el paso 5), pero un método async devuelve un valor de la tarea cuando se suspende el trabajo (los pasos 3 y 6).Cuando el método async completa finalmente el trabajo, se marca la tarea como completo y el resultado, si existe, se almacena en la tarea.

Para obtener más información sobre el flujo de control, vea Flujo de control en programas asincrónicos (C# y Visual Basic).

Métodos de la API Async

Tal vez se pregunte dónde encontrar métodos como GetStringAsync que programación admiten async.El .NET Framework 4.5 contiene muchos miembros que trabajan con async y await.Se pueden reconocer estos miembros por el sufijo "Async" en su nombre y un retorno de tipo Task o Task<TResult>.Por ejemplo, la clase System.IO.Stream contiene métodos como CopyToAsync, ReadAsync y WriteAsync junto con los métodos sincrónicos CopyTo, Read y Write.

Windows en tiempo de ejecución también contiene muchos métodos que puede utilizar con el async y aguardar en aplicaciones de Tienda Windows.Para obtener más métodos de información y de ejemplo, vea QuickStart: mediante el operador aguardar para programación asincrónicaProgramación asincrónica (aplicaciones de almacén de Windows), y WhenAny: Puente entre .NET Framework y Windows en tiempo de ejecución (C# y Visual Basic).

Subprocesos

La intención de los métodos async es ser aplicaciones no bloqueantes.Una expresión await en un método asincrónico no bloquea el subproceso actual mientras la tarea esperada se está ejecutando.En vez de ello, la expresión declara el resto del método como una continuación y devuelve el control al invocador del método asincrónico.

El async y espera palabras clave no hace que los subprocesos adicionales que se van a crear.Utilizar métodos async no requiere varios subprocesos, ya que un método asincrónico no se ejecuta en su propio subproceso.El método se ejecuta en el contexto de sincronización actual y ocupa tiempo en el subproceso sólo cuando el método está activo.Puede utilizar Task.Run para mover el trabajo de CPU- límite a un subproceso de fondo, pero un subproceso de fondo no ayuda a un proceso que simplemente está esperando resultados esté disponible.

El enfoque async- basado en la programación asincrónica es preferible a los enfoques existentes en casi cada caso.En concreto, este enfoque es mejor que BackgroundWorker para las operaciones de IO- límite porque el código es más fácil y no se tiene que protegerse contra las condiciones de carrera.Junto con Task.Run, la programación async es mejor que BackgroundWorker para las operaciones de CPU- límite porque la programación async separa los detalles de coordinación de ejecutar el código de trabajo que Task.Run transfiere el threadpool.

Async y Await

Si especifica que un método es un método async utilizando un modificador de Async o de async, habilita las dos funciones siguientes.

  • El método marcado async puede utilizar Espera o espera para notificar los puntos de suspensión.El operador aguardar indica al compilador que el método async no pueda continuar último que señala hasta que se complete el proceso aguardado asincrónico.Mientras tanto, el control vuelve al llamador del método async.

    La suspensión de un método async en una expresión de aguardar no constituye a una salida de método, y los bloques de finally no se ejecutan.

  • El método marcado se puede propio async aguardar por los métodos que lo llama.

Un método async normalmente contiene una o más apariciones de un operador de aguardar, pero la ausencia de espera expresiones no produce un error del compilador.Si un método async no utiliza un operador de aguardar para marcar un punto de suspensión, el método se ejecuta como ocurre un método sincrónico, a pesar de modificador async.El compilador detecta una advertencia para dichos métodos.

Async, async, Await y await son palabras clave de contexto.Para mayor información y ejemplos, consulte los siguientes temas:

Tipos de retorno y parámetros

En la programación de.NET Framework, un método async devuelve normalmente Task o Task<TResult>.Dentro de un método async, se aplican a un operador de aguardar a una tarea que devuelve una llamada a otro método async.

Se especifica el tipo de retorno Task<TResult> si el método contiene una instrucción Return (Visual Basic) o return (C#) que especifica un operando de tipo TResult.

Utiliza Task como tipo de valor devuelto si el método no tiene ninguna instrucción return ni tiene una instrucción return que no devuelve un operando.

El ejemplo siguiente se muestra cómo declarar y llama a un método que devuelve 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();

Cada tarea devuelta representa el trabajo en curso.Una tarea encapsula la información sobre el estado del proceso asincrónico y, finalmente, el resultado final del proceso o la excepción que el proceso provoca si no tiene éxito.

Un método async también puede ser un método de Sub (Visual Basic) o tener un tipo de valor devuelto de void (C#).Utilizan este tipo de valor devuelto principalmente para definir controladores de eventos, donde se requiere un tipo de valor devuelto de void.Los controladores de eventos Async sirven a menudo como punto de partida para programas async.

No se puede esperar a un método async que sea un procedimiento de tipo Sub o que tenga tipo de retorno void y el invocador de un método con tipo de retorno void no puede capturar ninguna excepción producida por éste.

Un método async no puede declarar parámetros ByRef en Visual Basic o parámetros ref u out en C#, pero el método puede invocar a otros métodos que tengan tales parámetros.

Para obtener más información y ejemplos, vea Tipos de valor devuelto de Async (C y Visual Basic).Para obtener más información sobre cómo detectar excepciones en métodos async, consulte try-catch (Referencia de C#) o Instrucción Try...Catch...Finally (Visual Basic).

API asincrónico en la programación de Windows en tiempo de ejecución tiene uno de los tipos de valor devuelto siguientes, que son similares a las tareas:

Para obtener más información y un ejemplo, vea QuickStart: mediante el operador aguardar para programación asincrónica.

Convención de nomenclatura

Por convención, se anexa “Async” a los nombres de los métodos que tienen un modificador de Async o de async.

Se puede ignorar esta convención cuando un evento, clase base, o interfaz sugiere un nombre diferente.Por ejemplo, no se debería cambiar el nombre de los manejadores de eventos, tales como Button1_Click.

Temas relacionados

Título

Descripción

Ejemplo

Walkthrough: Acceso a web usando Async y Await (C# y Visual Basic)

Muestra cómo convertir una solución sincrónica de WPF a una solución asincrónico WPF.La aplicación descarga una serie de sitio Web.

Ejemplo Async: Obtener acceso al tutorial web (C# y Visual Basic)

Cómo: Ampliar el tutorial usando Task.WhenAll (C# y Visual Basic)

Agrega Task.WhenAll al anterior tutorial.El uso de WhenAll inicia todas las descargas al mismo tiempo.

Cómo: Hacer varias solicitudes web en paralelo (C# y Visual Basic)

Demuestra cómo comenzar varias tareas al mismo tiempo.

Ejemplo Async: Haga Varias solicitudes web en paralelo (C# y Visual Basic)

Tipos de valor devuelto de Async (C y Visual Basic)

Muestra los tipos que los métodos async pueden devolver y explica cuando cada tipo es adecuado.

Flujo de control en programas asincrónicos (C# y Visual Basic)

Los seguimientos el flujo de control con una sucesión de aguarda detalladamente expresiones en un programa asincrónico.

Ejemplo Async: Flujo de control en programas Async (C# y Visual Basic)

Ajustar la aplicación de Async (C# y Visual Basic)

Muestra cómo agregar la siguiente funcionalidad a la solución asincrónica.

Ejemplo Async: Ajustando la aplicación de (C# y Visual Basic)

Controlar cómo se vuelve a entrar en aplicaciones asincrónicas (C# y Visual Basic)

Muestra cómo controlar los casos en los que se reinicia una operación asincrónica activo mientras se ejecuta.

WhenAny: Puente entre .NET Framework y Windows en tiempo de ejecución (C# y Visual Basic)

Muestra cómo unir entre los tipos de tareas en .NET Framework e IAsyncOperations en Windows en tiempo de ejecución para poder utilizar WhenAny con un método de Windows en tiempo de ejecución.

Ejemplo Async: Puente entre .NET y el tiempo de ejecución de Windows (AsTask y WhenAny)

Cancelación: Puente entre .NET Framework y Windows en tiempo de ejecución (C# y Visual Basic)

Muestra cómo unir entre los tipos de tareas en .NET Framework e IAsyncOperations en Windows en tiempo de ejecución para poder utilizar CancellationTokenSource con un método de Windows en tiempo de ejecución.

Ejemplo Async: Puente entre .NET y el tiempo de ejecución de Windows (AsTask y Cancelación)

Usar Async en acceso a archivos (C# y Visual Basic)

Las listas y muestran las ventajas de usar el async y los aguarda para tener acceso a archivos.

Tutorial: Usar el depurador con métodos asincrónicos

Muestra el flujo de control en una instrucción await y muestra el comportamiento de los comandos Step Into, Step Over, y Step Out en métodos asincrónicos.

Modelo asincrónico basado en tareas (TAP)

Describe un nuevo patrón de asincronía en el .NET Framework.El patrón está basado en los tipos Task y Task<TResult>.

QuickStart: Llamada API asincrónico en C# o Visual Basic

Muestra cómo utilizar el async y aguardarlo en una aplicación de Tienda Windows.

Programación asincrónica (aplicaciones de almacén de Windows)

Proporciona información general sobre la programación asincrónica en Windows en tiempo de ejecución.

Vídeos Async en el canal 9

Proporciona vínculos a una serie de vídeos sobre programación async.

Ejemplo completo

El código siguiente es el archivo MainWindow.xaml.vb o MainWindow.xaml.cs de la aplicación de (WPF) de Windows Presentation Foundation que este tema explica.Puede descargar el ejemplo de Ejemplo Async: Ejemplo de “programación asincrónica con Async y Await”.

' 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.

Vea también

Referencia

async (Referencia de C#)

await (Referencia de C#)

Await (Operador) (Visual Basic)

Async (Visual Basic)