Я пытаюсь выяснить, что я делаю неправильно здесь. Я уверен, что это что-то глупое, но я мог бы использовать дополнительные глаза, чтобы понять, что это такое. Я пытаюсь создать рабочий сервис, которому вы можете назначить делегата рабочего действия. Когда я пытаюсь поймать исключение, созданное делегатом рабочего действия, обработчик не вызывается. Я думаю, это потому, что мое действие на самом деле является асинхронным методом, который возвращает Task, и его не ждут. Но как я должен знать, что делегат асинхронен? Почему C# позволяет мне назначать метод, который возвращает задачу в переменную действия, которая должна возвращать void?Обработка исключений с делегатом async
Любая помощь будет оценена!
[Fact]
public async Task CanCatchExceptions() {
var worker = new Worker {
WorkAction = async item => await Throws()
};
worker.DoWork(new WorkItem { Id = 1 });
}
public class Worker {
// would prefer to keep work action simple and not require a Task.
public Action<WorkItem> WorkAction { get; set; }
public void DoWork(WorkItem item) {
try {
WorkAction(item);
} catch {
Debug.WriteLine("Handled");
}
}
}
public class WorkItem {
public int Id { get; set; }
}
public async Task Throws() {
throw new ApplicationException();
}
Итак, один из вариантов - установить WorkAction = item => Throws(). Wait(), но я до сих пор не понимаю, почему мне разрешено назначать переменную типа Action с переменной типа Func . –
Я думаю, что ответ Стивена касается этого. Но повторить: на языке есть специальные правила, позволяющие это делать. Это будет подразумевать, что 'async Task' будет эквивалентно' async void', что и происходит в вашем случае, позволяя использовать выражение лямбда для типа делегата 'Action'. Но обратите внимание, что это преобразование не изменяет поведение метода async; он по-прежнему возвращается в первом выражении 'await', и поэтому, если не ожидаемый (который вы не можете, если это' void'), вызывающий может (и обычно делает) завершить до того, как делает метод 'async'. –