В конце метода async я должен вернуться или подождать?
В конце метода async, возвращающего задачу, если я вызываю другой метод async, я мог бы либо await
, либо return
выполнить его задачу. Каковы последствия каждого?
Task FooAsync()
{
return BazAsync(); // Option A
}
async Task BarAsync()
{
await BazAsync(); // Option B
}
Ответы
Ответ 1
Вы не можете вернуть задачу, если сам метод объявлен как async
- поэтому это не сработает, например:
async Task BarAsync()
{
return BazAsync(); // Invalid!
}
Для этого потребуется тип возврата Task<Task>
.
Если ваш метод просто выполняет небольшую работу, а затем вызывает только один метод асинхронизации, тогда ваш первый вариант прекрасен и означает, что в нем задействовано еще меньше задач. Вы должны знать, что любые исключения, возникающие в вашем синхронном методе, будут передаваться синхронно, хотя, действительно, именно так я предпочитаю обрабатывать проверку аргументов.
Это также общий шаблон для реализации перегрузки, например. с помощью токена отмены.
Просто имейте в виду, что если вам нужно перейти на ожидание чего-то другого, вам нужно сделать вместо него метод async. Например:
// 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();
}
Ответ 2
Посмотрите эту ссылку, где описано: 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();
}