Явно используйте 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>?

Ответы на вопрос(2)

Ваш ответ на вопрос