【问题标题】:How to catch CancellationToken.ThrowIfCancellationRequested如何捕获 CancellationToken.ThrowIfCancellationRequested
【发布时间】:2017-05-03 20:11:42
【问题描述】:

当这部分代码被执行时

cancellationToken.ThrowIfCancellationRequested();

try catch 块不处理 exception

    public EnumerableObservable(IEnumerable<T> enumerable)
    {
        this.enumerable = enumerable;
        this.cancellationSource = new CancellationTokenSource();
        this.cancellationToken = cancellationSource.Token;


        this.workerTask = Task.Factory.StartNew(() =>
        {
            try
            {
                foreach (var value in this.enumerable)
                {
                    //if task cancellation triggers, raise the proper exception
                    //to stop task execution

                    cancellationToken.ThrowIfCancellationRequested();

                    foreach (var observer in observerList)
                    {
                        observer.OnNext(value);
                    }
                }
            }
            catch (AggregateException e)
            {
                Console.Write(e.ToString());                    
            }
        }, this.cancellationToken);

    }

【问题讨论】:

  • 赶上OperationCanceledException

标签: c# task task-parallel-library cancellationtokensource cancellation-token


【解决方案1】:

AggregateExceptions 在异步操作期间发生可能的大量异常时抛出。它们包含所有引发的异常,例如在链式 Tasks(通过 .ContinueWith)或级联 async/await 调用中。

正如@Mitch Stewart 指出的那样,在您的示例中,要处理的正确异常类型是OperationCancelledException

【讨论】:

  • 实际上,异常方式更好,如果你使用异常,如果引发异常的令牌与你传递给Task.Run或@的令牌相同,它将使workerTask.IsCanceled == true 987654330@
  • 当然,但是通过优雅的取消,可以更好地控制异步执行的实际终止。 TPL 开发团队首先实施 Cancellatio-infrastructure 有很多充分的理由,因为以前的 Thread-Model 在默认情况下没有提供这种机制。另请参阅 2004 年关于 why Thread.Abort is evil 的这篇文章
  • 我不明白你的评论。使用ThrowIfCancellationRequestedis considered graceful cancellation。不知道你为什么提出 Thread.Abort。
  • 是的,我明白你的意思了。我想我在这里混合了概念/术语,没关系。将删除建议轮询方法的部分;)。并且感谢您将我的思想推向正确的方向;) Thread.Abort 确实有点偏离主题。
  • 链式任务和级联异步/等待调用都不会导致AggregateException
【解决方案2】:

由于 ThrowIfCancellationRequested() 引发 OperationCanceledException 类型的异常,您必须捕获 OperationCanceledException 或其基类之一。

https://msdn.microsoft.com/en-us/library/system.operationcanceledexception(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2013-09-19
    • 2012-03-27
    • 2021-12-11
    • 2014-12-10
    • 2017-10-06
    • 2021-06-15
    相关资源
    最近更新 更多