2

在 Adam Freeman 的 Pro .NET 4 Parallel Programming in C# 的 Visual Studio 2012 Listing_07 下的控制台应用程序中运行时,当我尝试取消任务时出现异常。对我来说,这似乎没有什么大不了的,因为我们OperationCanceledException在任务中检测到取消尝试时抛出(或者看起来如此)。

这是一个错误还是我错过了什么?这个问题基本上出现在他所有的任务取消示例中!我只能假设自从这本书进入商店(2010 年)以来,任务库中的某些内容发生了变化?

// create the cancellation token source
CancellationTokenSource tokenSource
    = new CancellationTokenSource();

// create the cancellation token
CancellationToken token = tokenSource.Token;

// create the task
Task task = new Task(() => {
    for (int i = 0; i < int.MaxValue; i++) {
        if (token.IsCancellationRequested) {
            Console.WriteLine("Task cancel detected");
            throw new OperationCanceledException(token);
        } else {
            Console.WriteLine("Int value {0}", i);
        }
    }
}, token);

// wait for input before we start the task
Console.WriteLine("Press enter to start task");
Console.WriteLine("Press enter again to cancel task");
Console.ReadLine();

// start the task
task.Start();

// read a line from the console.
Console.ReadLine();

// cancel the task
Console.WriteLine("Cancelling task");
tokenSource.Cancel();

// wait for input before exiting
Console.WriteLine("Main method complete. Press enter to finish.");
Console.ReadLine();
4

2 回答 2

1

异常被 TPL 捕获,Task 进入 Canceled 状态。因此,虽然您会看到异常(如果您在调试器中打开了异常),但它会被处理。

正如 leon 提到的,您应该使用该CancellationToken.ThrowIfCancellationRequested方法,而不是明确地进行检查 + 扔自己。

此页面提供了有关取消任务的详细信息:http: //msdn.microsoft.com/en-us/library/dd997396.aspx

于 2012-11-26T14:25:22.700 回答
1

没有尝试捕获来使异常静音。当您按两次回车时,它就会被抛出。不就是为了这样的行为吗?将它包裹在 try 'n catch 中,它应该是优雅的。

                try
                {
                    for (int i = 0; i < int.MaxValue; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            Console.WriteLine("Task cancel detected");
                            token.ThrowIfCancellationRequested();
                        }
                        else
                        {
                            Console.WriteLine("Int value {0}", i);
                        }
                    }
                }
                catch(OperationCanceledException e)
                {
                    Console.WriteLine("Task cancelled via token!");
                }

还有一个方便的 CancelletionToken.ThrowIfCancellationRequested() 方法可以用来捕捉。

于 2012-11-24T17:27:10.483 回答