Явно используйте Func <Task> для асинхронной лямбда-функции, когда доступна перегрузка Action
Чтение оконченоэто сообщение в блоге о некоторых ошибках асинхронного / ожидающего C # 5. В 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)
какого типа скомпилирована асинхронная анонимная функция?async void
илиFunc<Task>
? Мое чувство кишки говорит, что оно скомпилируется доasync void
просто потому, что это не универсальный тип, однако компилятор C # может быть умным и датьFunc<Task>
предпочтение типов.
Кроме того, есть ли способ явно объявить, какую перегрузку я хочу использовать? Я знаю, что могу просто создать новый экземплярFunc<Task>
и передать там асинхронную лямбда-функцию, но она все равно будет скомпилирована доasync void
а затем передать это в конструкторFunc<Task>
, Каков идеальный способ убедиться, что он скомпилирован какFunc<Task>
?