通过在 Register 回调中调用 ThrowIfCancellationRequested

我正在尝试迁移到使用 .NET 中的 CancellationToken/Src 构造,例如:https: //learn.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-management-threads


我的基本问题是关于对取消请求做出反应。


就我而言,我有一些长时间运行的处理,这对于一致性并不重要。当取消请求到达时,我无法承受“轮询”的模式,例如:


        while (!_token.IsCancellationRequested)

        {

            DoProcessing(...)

        }

因为处理过程可能需要几分钟,而我真的想立即退出。


我的问题是,正确的方法是否是简单地使用此设置:


    public void Start()

    {

        _token.Register(() => _token.ThrowIfCancellationRequested());


        // Continuously process stuff.

        while (!_token.IsCancellationRequested)

        {

            DoProcessing(...)

        }

    }

也就是说,注册一个回调,该回调只会抛出 OperationCanceledException。


我可以在这里阅读:https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancel?view=netframework-4.8,即:


我们建议使用 CancellationToken 注册的可取消操作和回调不要抛出异常。


然而...


立即中断我的处理(而不是轮询)并仍然遵守框架规定的“规则”的正确方法是什么?


蝴蝶刀刀
浏览 93回答 1
1回答

慕容3067478

我可以理解这句话似乎建议不要使用ThrowIfCancellationRequested,但事实并非如此——使用ThrowIfCancellationRequested是合适的。有几个来源表明使用ThrowIfCancellationRequested是合适的:ThrowIfCancellationRequested表明这是正确的方法。抛出OperationCanceledException是 TPL 中表达“您调用的方法被取消”的惯用方式。不要反对它——只是期待它。Microsoft 的此消息 表明这ThrowIfCancellationRequested是正确的方法。成功取消涉及请求代码调用 CancellationTokenSource.Cancel 方法,以及用户委托及时终止操作。您可以使用以下选项之一终止操作:只需从委托返回即可[剪掉该项目符号的其余部分]通过抛出 OperationCanceledException 并向其传递请求取消的令牌。执行此操作的首选方法是使用 ThrowIfCancellationRequested 方法。以这种方式取消的任务将转换为已取消状态,调用代码可以使用该状态来验证任务是否响应了其取消请求还有一个代码示例演示如何ThrowIfCancellationRequested正确使用。进一步阅读此 Microsoft 源代码的另一句话:当任务实例观察到用户代码引发的 OperationCanceledException 时...任务会将其解释为确认取消并转换到“已取消”状态。...另请注意,其他异常的存在也会导致任务转换到Faulted状态......我怀疑(这只是我试图协调两个来源)这就是您引用的建议所指的内容——这是一个避免破坏取消机制准确指示任务状态为已取消或故障的能力的建议
打开App,查看更多内容
随时随地看视频慕课网APP