背景:
我有一个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:
如果您丢弃不稳定的解决方案(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取消任务而不显式检查任务内部?
发布评论