Почему OnlyOnFaults не перехватил исключение в taskObject.Wait ()? - PullRequest
0 голосов
/ 23 марта 2019

Я изучаю и экспериментирую с продолжением задачи, но я не знаю, как исключение может пройти через TaskContinuationOption.OnlyOnFaulted.

Насколько я знаю, Task.Wait() предоставляет место, где программа можетперехватить любые исключения, которые могут быть сгенерированы задачей, но я не знаю, почему она возвращает исключение, но задача с TaskContinuationOption.OnlyOnFaulted продолжается.

Task t1 = Task.Factory.StartNew(()=> {
    Console.WriteLine("T1 started");
    throw new Exception();
});

Task tFault = t1.ContinueWith((x)=> {
    Console.WriteLine("T fault started");

}, TaskContinuationOptions.OnlyOnFaulted);

Task t3 = tFault.ContinueWith((x)=> {
    Console.WriteLine("T3 started");
});
t1.Wait();

Я ожидаю, что t1 будет ждать связанных задачзавершить без исключения.

1 Ответ

1 голос
/ 24 марта 2019

С await t1 вы явно задаете точку приостановки для t1, которая вызывает повторное генерирование исключения, это ожидаемое поведение ( docs.microsoft.com ):

Если вы ожидаете асинхронный метод, возвращающий задачу, который вызывает исключение, оператор await сбрасывает исключение.

Однако ваши ожидания частично верны, потому что даже t1 выдает исключение t2 и t3 будет запланировано и в конечном итоге выполнено.


В качестве примечания, есть несколько проблем с вашим кодом.Вы используете опасные API, StartNew и ContinueWith.Обсуждаются проблемы: start и continue .

Рекомендуется использовать async\await вместо ContinueWith.Также вместо StartNew лучше использовать Run.

Task t1 = Task.Run(() =>
{
    Console.WriteLine("T1 started");
    throw new Exception();
});

var t2 = ContinueAfterT1(t1);
var t3 = ContinueAfterT2(t2);

await t3;

, где

async Task ContinueAfterT1(Task t1)
{
    try
    {
        await t1;
    }
    catch (Exception)
    {
        Console.WriteLine("T fault started");
    }
}

async Task ContinueAfterT2(Task t2)
{
    await t2;
    Console.WriteLine("T3 started");
}
...