Чтение этого сообщения в блоге о некоторых ошибках С# 5 async/await. Он упоминает в Gotcha # 4 нечто довольно глубокое и о котором я раньше не думал.
Вкратце, он охватывает сценарий, в котором у вас есть метод с двумя перегрузками, который принимает Action
и тот, который принимает Func<Task>
(например, Task.Run
). Эта проблема коренится в аргументе о том, что методы async void
должны использоваться только для обработчиков событий, при этом сообщение затем переходит к изображению следующего сценария. Что делает компилятор, когда с помощью лямбда-функции, такой как следующая, можно скомпилировать оба Func<Task>
и Action
:
Task.Run(async () => {
await Task.Delay(1000);
});
Поскольку Task.Run
имеет подписи как Task.Run(Func<Task>)
, так и Task.Run(Action)
, какой тип представляет собой асинхронную анонимную функцию, скомпилированную? A async void
или Func<Task>
? У меня возникает ощущение, что он скомпилируется до async void
только потому, что его не-общий тип, однако компилятор С# может быть умным и давать предпочтение Func<Task>
.
Также есть способ явно объявить, какую перегрузку я хочу использовать? Я знаю, что могу просто создать новый экземпляр Func<Task>
и передать там функцию async lambda, но он все равно будет скомпилирован до async void
, а затем передаст это в конструктор Func<Task>
. Каков идеальный способ убедиться, что он скомпилирован как Func<Task>
?