SLaks и Killercam ответы хорошие;Я подумал, что просто добавлю немного контекста.
Ваш первый вопрос по существу о том, какие методы можно пометить async
.
Метод, помеченный как async
canвозврат void
, Task
или Task<T>
.В чем различия между ними?
A Task<T>
можно ожидать возвращения асинхронного метода, и когда задача завершится, она предложит T.
A Task
returnможно ожидать асинхронный метод, и когда задача будет завершена, запланировано выполнение продолжения задачи.
A void
возвращение асинхронного метода не ожидается;это метод «огонь и забудь».Он работает асинхронно, и вы не можете сказать, когда это будет сделано.Это более чем немного странно;как говорит SLaks, обычно вы делаете это только при создании асинхронного обработчика событий.Событие срабатывает, обработчик выполняется;никто не собирается «ждать» задачи, возвращаемой обработчиком событий, потому что обработчики событий не возвращают задачи, и даже если они это сделают, какой код будет использовать задачу для чего-то?Обычно это не код пользователя, который передает управление обработчику.
Ваш второй вопрос, в комментарии, по сути о том, что может быть await
ed:
Какие методы могут быть await
ред?Может ли метод возврата void быть await
ed?
Нет, метод возврата void не может ожидаться.Компилятор преобразует await M()
в вызов M().GetAwaiter()
, где GetAwaiter
может быть методом экземпляра или методом расширения.Ожидаемое значение должно быть таким, за которое вы можете получить ожидающего;Очевидно, что метод, возвращающий пустоту, не дает значения, из которого вы можете получить ожидающего.
Task
Методы возврата могут давать ожидаемые значения.Мы ожидаем, что третьи стороны захотят создать свои собственные реализации Task
-подобных объектов, которые можно ожидать, и вы сможете их ожидать.Однако вам не разрешат объявлять async
методы, которые возвращают что-либо кроме void
, Task
или Task<T>
.
(ОБНОВЛЕНИЕ: моё последнее предложение может быть сфальсифицировано будущей версией C #; есть предложение разрешить типы возврата, отличные от типов задач, для асинхронных методов.)
(ОБНОВЛЕНИЕ:вышеупомянутая особенность сделала это в C # 7.)