Task.WhenAll (). ContinueWith () генерирует непредвиденное исключение Task Cancelled - PullRequest
1 голос
/ 22 апреля 2020

Я использую Task.WhenAll для одновременного планирования задач (более или менее, конечно) и хочу перебрасывать все исключения, а не первое, что будет делать Task.WhenAll. Поэтому я хочу выполнить продолжение всякий раз, когда какое-либо дочернее задание не выполнено или было отменено. Вот что означает NotOnRanToCompletion, верно?

Ну, это на самом деле работает, но в случае, если все Задачи действительно выполнены, я получаю исключение Задача отменена в продолжении?

 var semaphore = new SemaphoreSlim(10);
            var tasks = portList.Select(
                async port =>
                    {
                        try
                        {
                            await semaphore.WaitAsync();
                            await this.AddDeviceAsync(bioprocessDevicesDto, template, port);
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    });
            await Task.WhenAll(tasks).ContinueWith(
                t =>
                    {
                        // this will make all inner exceptions available
                        // never null
                        throw t.Exception;
                    },
                TaskContinuationOptions.NotOnRanToCompletion).ConfigureAwait(false);

a

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Такое поведение является задним числом и задокументировано .

Обратите внимание, что ваш код не await содержит задачу, возвращенную из WhenAll; это await продолжение из ContinueWith.

ContinueWith - это низкоуровневый метод с опасным поведением по умолчанию . Используйте await вместо:

var tasks = portList.Select(...);
var allTask = Task.WhenAll(tasks);
try { await allTask; }
catch { throw allTask.Exception; }
1 голос
/ 22 апреля 2020

Когда вы смотрите на TaskContinuationOptions для NotOnRanToCompletion, в нем говорится:

Эта опция недопустима для продолжений нескольких задач.

Я бы попробовал изменить NotOnRanToCompletion на другую опцию, которая обрабатывает многозадачные продолжения.

...