await (Referencia de C#)

El operador await se aplica a una tarea en un método asincrónico para suspender la ejecución del método hasta que se complete la tarea esperada. La tarea representa el trabajo en curso.

El método asincrónico en el que se utiliza await debe modificarse mediante la palabra clave async. Este tipo de método, definido mediante el modificador async y que generalmente contiene una o más expresiones await, se denomina método asincrónico.

NotaNota

Las palabras clave async y await se incluyeron en Visual Studio 2012.Para obtener una introducción a la programación asincrónica, consulte Programación asincrónica con Async y Await (C# y Visual Basic).

La tarea a la que se aplica el operador await normalmente es el valor devuelto de una llamada a un método que implementa el patrón asincrónico basado en tareas. Entre los ejemplos se incluyen valores del tipo Task o Task.

En el código siguiente, el método GetByteArrayAsync HttpClient devuelve Task<byte[]>, getContentsTask. La tarea es una promesa de producir la matriz de bytes real cuando finaliza la tarea. El operador await se aplica a getContentsTask para suspender la ejecución en SumPageSizesAsync hasta que se complete getContentsTask. Mientras tanto, el control vuelve al llamador de SumPageSizesAsync. Cuando getContentsTask haya finalizado, la expresión await se evalúa como una matriz de bytes.

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);
    // . . .
}
Nota importanteImportante

Para obtener el ejemplo completo, vea Walkthrough: Acceso a web usando Async y Await (C# y Visual Basic).Puede descargar el ejemplo desde Ejemplos de código para desarrolladores en el sitio web de Microsoft.El ejemplo está en el proyecto AsyncWalkthrough_HttpClient.

Tal como se muestra en el ejemplo anterior, si se aplica await al resultado de una llamada al método que devuelve Task<TResult>, el tipo de la expresión await es TResult. Si await se aplica al resultado de una llamada al método que devuelve Task, el tipo de la expresión await será void. En el siguiente ejemplo se ilustra la diferencia.

// 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();

Una expresión await no bloquea el subproceso en el que se ejecuta. En su lugar, hace que el compilador inscriba el resto del método asincrónico como una continuación en la tarea esperada. El control devuelve al llamador del método asincrónico. Cuando la tarea completa, invoca su continuación y la ejecución del método asincrónico se reanuda donde se quedó.

Una expresión await solo puede aparecer en el cuerpo de un método envolvente inmediato, una expresión lambda o un método anónimo marcado con el modificador async. El término await solo sirve como palabra clave en ese contexto. En otra parte, se interpretará como identificador. Dentro del método, la expresión lambda o el método anónimo, no puede aparecer una expresión await en el cuerpo de una función sincrónica, en una expresión de consulta, en el bloque catch o finally de una instrucción de control de excepciones, en el bloque de una instrucción lock o en un contexto de unsafe.

Excepciones

La mayoría de los métodos asincrónicos devuelven un objeto Task o Task. Las propiedades de la tarea devuelta llevan información acerca de su estado e historial, por ejemplo, si la tarea se ha completado, si el método asincrónico produjo una excepción o si se ha cancelado y cuál es el resultado final. El operador await tiene acceso a esas propiedades.

Si espera un método asincrónico task-returning que cause una excepción, el operador await volverá a generar la excepción.

Si espera un método asincrónico task-returning que se cancele, el operador await volverá a generar OperationCanceledException.

Una única tarea en estado de error puede reflejar varias excepciones. Por ejemplo, la tarea podría ser el resultado de una llamada a Task.WhenAll. Cuando espera dicha tarea, la operación await vuelve a generar únicamente una de las excepciones. Sin embargo, no puede predecir cuál de las excepciones se vuelve a generar.

Para obtener ejemplos de control de errores en métodos asincrónicos, vea try-catch (Referencia de C#).

Ejemplo

El ejemplo siguiente de Windows Forms muestra el uso de await en un método asincrónico, WaitAsynchronouslyAsync. Compare el comportamiento de dicho método con el de WaitSynchronously. Sin un operador await aplicado a una tarea, WaitSynchronously se ejecuta sincrónicamente a pesar del uso del modificador async en su definición y una llamada a Thread.Sleep en el cuerpo.

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

Vea también

Tareas

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

Referencia

async (Referencia de C#)

Conceptos

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