如何捕获CancellationToken.ThrowIfCancellationRequested

3
当执行此代码段时。
cancellationToken.ThrowIfCancellationRequested();
< p > try catch块不能处理异常

    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);

    }

6
捕获OperationCanceledException异常。 - JSteward
2个回答

2

2

1
实际上,使用异常处理的方式更好。如果您使用异常处理,当引发异常的令牌与传递给Task.RunTask.Factory.StartNew的令牌相同时,它将使workerTask.IsCanceled == true - Scott Chamberlain
当然,但是通过优雅的取消,您可以更好地控制异步执行的实际终止,这是许多TPL开发团队最初实施Cancellation基础设施的好理由之一,因为以前的线程模型默认情况下不提供此类机制。此外,可以参考2004年关于为什么Thread.Abort是有害的的帖子。 - earloc
2
我不理解你的评论。使用ThrowIfCancellationRequested被认为是优雅的取消。不确定你为什么提到了Thread.Abort。 - Scott Chamberlain
是的,我明白你的观点了。我想我在这里混淆了概念/术语,没关系。我会删除暗示轮询方法的那部分内容;感谢你引导我思考正确的方向。 不过,Thread.Abort 确实有点跑题了。 - earloc
1
既不会因为链接任务,也不会因为级联的异步/等待调用而引发“AggregateException”。 - Stephen Cleary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接