У меня есть несколько задач, которые принимают токен отмены и соответственно вызывают ThrowIfCancellationRequested. Эти задачи будут выполняться одновременно с использованием Task.WhenAll. Я хочу, чтобы все задачи отменялись, когда какие-либо задачи вызывают исключение. Я добился этого с помощью Select и ContinueWith:
Код: Выделить всё
var cts = new CancellationTokenSource();
try
{
var tasks = new Task[] { DoSomethingAsync(cts.Token), ... } // multiple tasks here
.Select(task => task.ContinueWith(task =>
{
if (task.IsFaulted)
{
cts.Cancel();
}
}));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
catch (SpecificException)
{
// Why is this block never reached?
}
Я не уверен, что это лучший способ сделать это, похоже, у него есть некоторые проблемы. Похоже, что исключение будет перехвачено внутри, всегда достигается код после WhenAll. Я не хочу, чтобы код после WhenAll достигался при возникновении исключения, я предпочитаю, чтобы исключение было выброшено, чтобы я мог перехватить его вручную на другом уровне стека вызовов. Какой лучший способ добиться этого? Если возможно, я бы хотел, чтобы стек вызовов остался нетронутым. Если возникает несколько исключений, лучше всего повторно создавать только первое исключение, а не AggregateException.
В связи с этим я попытался передать токен отмены в ContinueWith следующим образом: Task.ContinueWith(lambda, cts.Token). Однако, когда возникает исключение в какой-либо задаче, это в конечном итоге вызовет TaskCanceledException вместо интересующего меня исключения. Я решил, что мне следует передать токен отмены в ContinueWith, потому что это приведет к отмене ContinueWith< /code> сам по себе, но я не думаю, что это то, что мне нужно.
Подробнее здесь:
https://stackoverflow.com/questions/423 ... -exception