async (Referencia de C#)

Use el modificador async para especificar que un método, una expresión lambda o un método anónimo es asincrónico. Si usa este modificador en un método o una expresión, se hace referencia al mismo como un método asincrónico. En el ejemplo siguiente se define un método asincrónico denominado ExampleMethodAsync:

public async Task<int> ExampleMethodAsync()
{
    //...
}

Si no está familiarizado con la programación asincrónica o no entiende cómo un método asincrónico usa el operador await para hacer el trabajo de larga duración sin bloquear el subproceso del autor de la llamada, lea la introducción de Programación asincrónica con async y await. El siguiente código se encuentra dentro de un método asincrónico y llama al método HttpClient.GetStringAsync:

string contents = await httpClient.GetStringAsync(requestUrl);

Un método asincrónico se ejecuta sincrónicamente hasta alcanzar la primera expresión await, en la que se suspende el método hasta que se complete la tarea en espera. Mientras tanto, el control vuelve al llamador del método, como se muestra en el ejemplo de la sección siguiente.

Si el método que la palabra clave async modifica no contiene una expresión o instrucción await, el método se ejecuta de forma sincrónica. Una advertencia del compilador alerta de cualquier método asincrónico que no contenga instrucciones de await, porque esa situación podría indicar un error. Vea Advertencia del compilador (nivel 1) CS4014.

La palabra clave async es contextual en el sentido de que es una palabra clave cuando modifica un método, una expresión lambda o un método anónimo. En todos los demás contextos, se interpreta como identificador.

Ejemplo

En el ejemplo siguiente se muestra la estructura y el flujo de control entre un controlador de eventos asincrónicos, StartButton_Click, y un método asincrónico, ExampleMethodAsync. El resultado del método asincrónico es el número de caracteres de una página web. El código es adecuado para una aplicación Windows Presentation Foundation (WPF) o de la Tienda Windows creada en Visual Studio; vea los comentarios del código para configurar la aplicación.

Puede ejecutar este código en Visual Studio como una aplicación Windows Presentation Foundation (WPF) o una aplicación de la Tienda Windows. Necesita un control de botón denominado StartButton y un control de cuadro de texto denominado ResultsTextBox. Recuerde establecer los nombres y el controlador de manera que tenga algo similar a esto:

<Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top" Width="75"
        Click="StartButton_Click" Name="StartButton"/>
<TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap"
         Text="&lt;Enter a URL&gt;" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/>

Para ejecutar el código como una aplicación WPF:

  • Pegue este código en la clase MainWindow en MainWindow.xaml.cs.
  • Agregue una referencia a System.Net.Http.
  • Agregue una directiva using a System.Net.Http.

Para ejecutar el código como una aplicación de la Tienda Windows:

  • Pegue este código en la clase MainPage en MainPage.xaml.cs.
  • Agregue directivas using para System.Net.Http y System.Threading.Tasks.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // ExampleMethodAsync returns a Task<int>, which means that the method
    // eventually produces an int result. However, ExampleMethodAsync returns
    // the Task<int> value as soon as it reaches an await.
    ResultsTextBox.Text += "\n";

    try
    {
        int length = await ExampleMethodAsync();
        // Note that you could put "await ExampleMethodAsync()" in the next line where
        // "length" is, but due to when '+=' fetches the value of ResultsTextBox, you
        // would not see the global side effect of ExampleMethodAsync setting the text.
        ResultsTextBox.Text += String.Format("Length: {0:N0}\n", length);
    }
    catch (Exception)
    {
        // Process the exception if one occurs.
    }
}

public async Task<int> ExampleMethodAsync()
{
    var httpClient = new HttpClient();
    int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length;
    ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";
    // After the following return statement, any method that's awaiting
    // ExampleMethodAsync (in this case, StartButton_Click) can get the
    // integer result.
    return exampleInt;
}
// The example displays the following output:
// Preparing to finish ExampleMethodAsync.
// Length: 53292

Importante

Para obtener más información sobre las tareas y el código que se ejecuta mientras se espera la finalización de una tarea, vea Programación asincrónica con async y await. Para ver un ejemplo completo de la consola que usa elementos similares, consulte el artículo Iniciar varias tareas asincrónicas y procesarlas a medida que se completan (C#).

Tipos de valor devueltos

Un método asincrónico puede tener los siguientes tipos de valor devuelto:

  • Task
  • Task<TResult>
  • void. Los métodos async void no suelen ser recomendables para código que no sea controladores de eventos dado que los autores de la llamada no pueden usar await con esos métodos y deben implementar otro mecanismo para informar sobre la finalización correcta o condiciones de error.
  • A partir de C# 7.0, cualquier tipo que tenga un método GetAwaiter accesible. El tipo System.Threading.Tasks.ValueTask<TResult> es una implementación de ese tipo. Está disponible agregando el paquete NuGet System.Threading.Tasks.Extensions.

El método asincrónico no puede declarar ningún parámetro in, ref o out, ni puede tener un valor devuelto de referencia, pero puede llamar a los métodos que tienen estos parámetros.

Se puede especificar Task<TResult> como el tipo de valor devuelto de un método asincrónico si la instrucción return del método especifica un operando de tipo TResult. Utilice Task si no se devuelve ningún valor significativo al completarse el método. Es decir, una llamada al método devuelve Task, pero cuando se completa Task, las expresiones await que esperan a que Task finalice se evalúan como void.

El tipo devuelto void se utiliza principalmente para definir controladores de eventos, que requieren ese tipo devuelto. El llamador de un método asincrónico que devuelva void no puede esperar a que finalice y no puede detectar las excepciones que el método inicia.

A partir de C# 7.0, devuelve otro tipo, normalmente un tipo de valor, que tiene un método GetAwaiter para minimizar las asignaciones de memoria en secciones críticas de rendimiento del código.

Para más información y ejemplos, vea Tipos de valor devueltos asincrónicos.

Vea también