Когда я использую функцию Task.WhenAll()
, и исключение отправляется в Задачу, генерируется новое исключение AggregateException, я могу поймать его, чтобы увидеть все исключения, которые произошли в Задания. Однако, когда я использую Task.WhenAny()
, исключение не выбрасывается. Вместо этого я должен проверить свойство Task.Exception
на значение, чтобы увидеть, произошло ли исключение. Это похоже на плохой запах кода, поскольку я должен был бы не забыть проверить свойство Task.Exception
каждый раз, когда я использую Task.WhenAny()
. Разве не должно быть лучшего способа?Как обрабатывать исключения при использовании Task Parallel Library Task.WhenAny()
Вот пример того, что я имею в виду:
private async void btnMultipleExceptions_Click(object sender, EventArgs e) {
var task1 = ThrowNotImplementedException();
var task2 = ThrowDivideByZeroException();
try {
Task task = await Task.WhenAny(task1, task2);
// Even if an exception is thrown in one of the tasks (in our case,
// task1 will throw first) no exception is thrown from
// the above await Task.WhenAny(). Instead, the exception is placed on the
// Task.Exception property. So I need to check for it every time
// I call Task.WhenAny()?
if (task.Exception != null) {
Console.WriteLine("Exceptions: " + string.Join(Environment.NewLine,
task.Exception.InnerExceptions.Select(x => x.Message).ToArray()));
} else {
Console.WriteLine("No Exceptions!");
}
} catch(Exception ex) {
// Try to catch all exceptions???
AggregateException allEx = ex as AggregateException;
if (allEx != null) {
Console.WriteLine("Exceptions: " + string.Join(Environment.NewLine,
allEx.InnerExceptions.Select(x => x.Message).ToArray()));
} else {
Console.WriteLine("Exceptions: " + ex.Message);
}
}
}
private async Task ThrowNotImplementedException() {
await Task.Delay(TimeSpan.FromSeconds(1));
throw new NotImplementedException();
}
private async Task ThrowDivideByZeroException() {
await Task.Delay(TimeSpan.FromSeconds(2));
throw new DivideByZeroException();
}
Благодарим вас за расширения. К сожалению, я думаю, что я все еще не вижу ничего очевидного. Если я использую 'waitait Task.WhenAny (task1, task2);' и следующая строка 'Console.WriteLine (« Без исключений »),' 'Console.WriteLine();' выполняется. Обработчик улова - нет. Есть ли что-то еще, что мне нужно делать при использовании 'Task.WhenAny()'? –
@HenryDaehnke Когда вы говорите 'ждут Task.WhenAny (task1, task2);' который разрешает 'Task', потому что' WhenAny' возвращает 'Task', поэтому его ждет 'Task'. Если вы 'await' it * снова * (или разворачиваете его перед его ожиданием), то вы ожидаете, что эта действительная задача сработала, а выполнение перейдет в блок' catch'. В этом весь ответ, вам нужно ждать внутренней задачи, а не внешней задачи. –
Servy
Хорошо, это действительно странно. По-видимому, «Task.WhenAny() не перебрасывает исключение, когда вы« ждете »его. Вместо этого вы можете «ждать» 'await' (т. Е.« Ждать ждут Task.WhenAny (task1, task2) »). Получил ответ от [link] (http://www.tomdupont.net/2014/09/await-await-taskwhenany.html). –