Async ожидание возврата Задача
Может кто-нибудь объяснить, что это значит, в синхронный метод? Если я попытаюсь изменить метод на async
, тогда VS жалуется на него.
Это работает:
public Task MethodName()
{
return Task.FromResult<object>(null);
}
Это не работает:
public async Task MethodName()
{
return Task.FromResult<object>(null);
}
Итак, в основном я хотел бы знать, что именно это означает: Task.FromResult<object>(null);
Ответы
Ответ 1
async
методы отличаются от обычных методов. Все, что вы возвращаете из методов async
, обернуто в Task
.
Если вы не вернете значение (void), оно будет завернуто в Task
, если вы вернетесь int
, оно будет завернуто в Task<int>
и т.д.
Если вашему асинхронному методу нужно возвратить int
, вы должны пометить тип возвращаемого метода как Task<int>
, и вы вернете plain int
, а не Task<int>
. Компилятор преобразует int
в Task<int>
для вас.
private async Task<int> MethodName()
{
await SomethingAsync();
return 42;//Note we return int not Task<int> and that compiles
}
Sameway, Когда вы возвращаете Task<object>
, возвращаемый тип метода должен быть Task<Task<object>>
public async Task<Task<object>> MethodName()
{
return Task.FromResult<object>(null);//This will compile
}
Поскольку ваш метод возвращает Task
, он не должен возвращать какое-либо значение. В противном случае он не будет компилироваться.
public async Task MethodName()
{
return;//This should work but return is redundant and also method is useless.
}
Имейте в виду, что метод async без оператора await
не async
.
Ответ 2
Вам нужно использовать ключевое слово await при использовании async, и возвращаемый тип функции должен быть общим. Ниже приведен пример с возвращаемым значением:
public async Task<object> MethodName()
{
return await Task.FromResult<object>(null);
}
Вот пример без возвращаемого значения:
public async Task MethodName()
{
await Task.CompletedTask;
}
Прочтите эти данные:
TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx и Задачи: http://msdn.microsoft.com/en-us/library/system.threading.tasks(v=vs.110).aspx
Async: http://msdn.microsoft.com/en-us/library/hh156513.aspx
Ожидание: http://msdn.microsoft.com/en-us/library/hh156528.aspx
Ответ 3
Добавление ключевого слова async - это просто синтаксический сахар, чтобы упростить создание конечного автомата. По сути, компилятор принимает ваш код,
public async Task MethodName()
{
return null;
}
И превращает его в;
public Task MethodName()
{
return Task.FromResult<object>(null);
}
Если ваш код имеет какие-либо ключевые слова await
, компилятор должен принять ваш метод и превратить его в класс для представления конечного автомата, необходимого для его выполнения. При каждом ключевом слове await
состояние переменных и стека будет сохранено в полях класса, класс добавит себя как крюк завершения к ожидаемой задаче, а затем вернется.
Когда эта задача завершится, ваша задача будет выполнена снова. Поэтому в верхнюю часть метода добавляется некоторый дополнительный код для восстановления состояния переменных и перехода в следующую панель вашего кода.
См. Что такое асинхронный и ожидающий генерировать? для примера gory.
Этот процесс имеет много общего с тем, как компилятор обрабатывает методы итератора с помощью операторов yield.