Pregunta Al final de un método asíncrono, ¿debo regresar o esperar?


Al final de un método asincrónico de devolución de tareas, si llamo a otro método asíncrono, podría await o return su tarea. ¿Cuáles son las consecuencias de cada uno?

    Task FooAsync()
    {
        return BazAsync();  // Option A
    }

    async Task BarAsync()
    {
        await BazAsync(); // Option B
    }

32
2017-07-26 16:58


origen


Respuestas:


No puede devolver la tarea si el método en sí es declarado async - entonces esto no funcionará, por ejemplo:

async Task BarAsync()
{
    return BazAsync(); // Invalid!
}

Eso requeriría un tipo de devolución de Task<Task>.

Si tu método es sólo haciendo una pequeña cantidad de trabajo y luego llamando sólo un método asíncrono, entonces su primera opción está bien, y significa que hay una tarea menos involucrada. Debe tener en cuenta que cualquier excepción arrojada dentro de su sincrónico El método se entregará sincrónicamente, de hecho, así es como prefiero manejar la validación de argumentos.

También es un patrón común para implementar la sobrecarga, p. por token de cancelación.

Solo ten en cuenta que si necesitas cambiar para esperar otra cosa, necesitarás convertirlo en un método asíncrono. Por ejemplo:

// Version 1:
Task BarAsync()
{
    // No need to gronkle yet...
    return BazAsync();
}

// Oops, for version 2 I need to do some more work...
async Task BarAsync()
{
    int gronkle = await GronkleAsync();
    // Do something with gronkle

    // Now we have to await BazAsync as we're now in an async method
    await BazAsync();
}

31
2017-07-26 17:03



Mira este enlace donde se describe: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // The body of the method should contain one or more await expressions.

    // Return statement specifies an integer result.
    return hours;
}

    // Calls to TaskOfTResult_MethodAsync from another async method.
private async void CallTaskTButton_Click(object sender, RoutedEventArgs e)
{
    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 body of the method should contain one or more await expressions.

    // The method has no return statement.  
}

    // Calls to Task_MethodAsync from another async method.
private async void CallTaskButton_Click(object sender, RoutedEventArgs e)
{
    Task returnedTask = Task_MethodAsync();
    await returnedTask;
    // or, in a single statement
    //await Task_MethodAsync();
}

2
2017-07-26 17:01