简体   繁体   English

处理在已取消的任务中引发的异常

[英]Handling exceptions thrown in a canceled Task

I'm working through the examples in the Exam Ref 70-483: Programming in C# book and have run into a problem with the following code from listing 1-44. 我正在研究《 考试参考书70-483:C#中的编程》中的示例,并且遇到了清单1-44中的以下代码的问题。 In this example, the author is trying to demonstrate that a continuation task has access to unhandled exceptions thrown in the antecedent task, and can handle them if it is appropriate to do so. 在这个例子中,作者试图证明延续任务可以访问在前任务中抛出的未处理异常,并且可以适当地处理它们。

static void Main(string[] args)
{
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    CancellationToken token = cancellationTokenSource.Token;

    Task task = Task.Run(() =>
    {
        while (!token.IsCancellationRequested)
        {
            Console.Write("*");
            Thread.Sleep(1000);
        }
        throw new OperationCanceledException();
    }, token).ContinueWith((t) =>
    {
        t.Exception.Handle((e) => true);
        Console.WriteLine("You have canceled the task.");
    }, TaskContinuationOptions.OnlyOnCanceled);

    Console.WriteLine("Press enter to stop the task.");
    Console.ReadLine();

    cancellationTokenSource.Cancel();
    task.Wait();

    Console.WriteLine("Press enter to end the application.");
    Console.ReadLine();
}

Unfortunately, this line of code in the continuation 不幸的是,这行代码在继续

t.Exception.Handle((e) => true);

throws an exception because t.Exception is null . 抛出异常,因为t.Exceptionnull

Setting a breakpoint at that line, I can see that t.Status is Canceled , not Faulted . 在该行设置一个断点,我可以看到, t.StatusCanceled ,没有Faulted Is this why the exception is not available? 这就是为什么没有例外的原因吗? What is the correct way to handle the exception thrown in the antecedent task? 处理先前任务中引发的异常的正确方法是什么?

Use 采用

task.ContinueWith(HandleError, TaskContinuationOptions.OnlyOnFaulted);

Cancelled tasks are not exceptional... And therefore will not include an exception. 取消的任务不是例外...因此不会包含异常。 Faulted ones will. 有过失的人会的。

Change the code for Listing 1-44 to: 将清单1-44的代码更改为:

Task task = Task.Run(() => { 
    while (true) 
    {
     token.ThrowIfCancellationRequested();
     Console.Write("*");
     Thread.Sleep(1000); }
    }, token).ContinueWith(t =>
 { Console.WriteLine("You have canceled the task"); }, TaskContinuationOptions.OnlyOnCanceled);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM