使用CancellationToken取消任务而不显式检查任务内部?

编程入门 行业动态 更新时间:2024-10-26 22:20:23
本文介绍了使用CancellationToken取消任务而不显式检查任务内部?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

背景:

我有一个Web应用程序,可以启动长期运行(无状态)的任务:

I have a web application which kicks off long running (and stateless) tasks:

var task = Task.Run(() => await DoWork(foo)) task.Wait();

由于它们已运行很长时间,因此我需要能够从单独的Web请求中将其取消.

Because they are long running, I need to be able to cancel them from a separate web request.

为此,我想使用CancellationToken并在令牌被取消后立即抛出异常.但是,根据我的阅读,任务取消是合作,这意味着任务正在运行的代码必须显式检查令牌以查看是否发出了取消请求(例如 CancellationToken.ThrowIfCancellation())

For this, I would like to use a CancellationToken and just throw an exception as soon as the token is canceled. However, from what I've read, Task Cancellation is cooperative, meaning the code the task is running must explicitly check the token to see if a cancellation request has been made (for example CancellationToken.ThrowIfCancellation())

我想避免在整个地方检查 CancellationToken.ThrowIfCancellation(),因为任务很长并且需要执行许多功能.我想我可以完成创建显式 Thread 的任务,但是我真的想避免手动进行线程管理.那就是...

I would like to avoid checking CancellationToken.ThrowIfCancellation() all over the place, since the task is quite long and goes through many functions. I think I can accomplish what I want creating an explicit Thread, but I would really like to avoid manual thread management. That said...

问题:是否可以在取消任务时自动在任务中引发异常,如果没有,是否有其他好的选择(模式等)来减少 CancellationToken.ThrowIfCancellation()对代码的污染?

Question: Is it possible to automatically throw an exception in the task when it has been canceled, and if not, are there any good alternatives (patterns, etc.) to reduce polluting the code with CancellationToken.ThrowIfCancellation()?

我想避免这样的事情:

async Task<Bar> DoWork(Foo foo) { CancellationToken.ThrowIfCancellation() await DoStuff1(); CancellationToken.ThrowIfCancellation() await DoStuff2(); CancellationToken.ThrowIfCancellation() await DoStuff3(); ... }

我觉得这个问题与这个问题足够,因为我我明确要求一种方法来减少检查取消令牌的调用,接受的答案会对此做出响应:每时每刻,在函数内部,调用token.ThrowIfCancellationRequested()"

I feel that this question is sufficiently different from this one because I'm explicitly asking for a way to minimize calls to check the cancellation token, to which the accepted answer responds "Every now and then, inside the functions, call token.ThrowIfCancellationRequested()"

推荐答案

是否可以在取消任务时自动在任务中引发异常,如果没有,是否有任何好的替代方法(模式等)来减少使用CancellationToken.ThrowIfCancellation()对代码的污染?

Is it possible to automatically throw an exception in the task when it has been canceled, and if not, are there any good alternatives (patterns, etc.) to reduce polluting the code with CancellationToken.ThrowIfCancellation()?

不,不.所有取消都是合作的.取消代码的最佳方法是使代码响应取消请求.这是唯一的好模式.

No, and no. All cancellation is cooperative. The best way to cancel code is to have the code respond to a cancellation request. This is the only good pattern.

我想我可以完成创建显式线程的操作

I think I can accomplish what I want creating an explicit Thread

不是真的.

此时,问题是如何取消无法取消的代码?"答案取决于您希望系统的稳定性:

At this point, the question is "how do I cancel uncancelable code?" And the answer to that depends on how stable you want your system to be:

  • 在不再需要该线程时,在单独的 Thread 和 Abort 线程中运行代码.就应用程序的不稳定性而言,这是最容易实现的方法,但也是最危险的方法.坦率地说,如果您曾经在应用程序中的任何地方调用 Abort ,除了标准的常规操作(如心跳/烟雾测试检查)之外,还应定期重新启动该应用程序.
  • 在不再需要该A​​ppDomain的单独的 AppDomain 和 Unload 中运行代码.这很难实现(您必须使用远程处理),并且在Core世界中不是一种选择.事实证明, AppDomain 甚至没有像应该保护的那样保护包含的应用程序,因此,使用此技术的任何应用程序也需要定期重新启动.
  • 在不再需要的进程中,在单独的 Process 和 Kill 中运行代码.这是最复杂的实现,因为您还需要实现某种形式的进程间通信.但这是取消无法取消的代码的唯一可靠的解决方案.
  • Run the code in a separate Thread and Abort the thread when it is no longer necessary. This is the easiest to implement but the most dangerous in terms of application instability. To put it bluntly, if you ever call Abort anywhere in your app, you should regularly restart that app, in addition to standard practices like heartbeat/smoketest checks.
  • Run the code in a separate AppDomain and Unload that AppDomain when it is no longer necessary. This is harder to implement (you have to use remoting), and isn't an option in the Core world. And it turns out that AppDomains don't even protect the containing application like they were supposed to, so any apps using this technique also need to be regularly restarted.
  • Run the code in a separate Process and Kill that process when it is no longer necessary. This is the most complex to implement, since you'll also need to implement some form of inter-process communication. But it is the only reliable solution to cancel uncancelable code.
  • 如果您丢弃不稳定的解决方案(1)和(2),那么剩下的唯一解决方案(3)就是大量的工作-比使代码可取消的方法更多.

    If you discard the unstable solutions (1) and (2), then the only remaining solution (3) is a ton of work - way, way more than making the code cancelable.

    TL; DR:仅使用取消API的设计用途即可.这是最简单,最有效的解决方案.

    TL;DR: Just use the cancellation APIs the way they were designed to be used. That is the simplest and most effective solution.

    更多推荐

    使用CancellationToken取消任务而不显式检查任务内部?

    本文发布于:2023-11-12 21:39:14,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1582594.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:而不   CancellationToken

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!