gpt4 book ai didi

c# - 使用 CancellationToken 取消任务而不在任务中明确检查?

转载 作者:太空宇宙 更新时间:2023-11-03 18:51:32 25 4
gpt4 key购买 nike

背景:

我有一个启动长时间运行(和无状态)任务的网络应用程序:

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

task.Wait();

因为它们运行时间很长,所以我需要能够从单独的 Web 请求中取消它们。

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

我想避免在整个地方检查 CancellationToken.ThrowIfCancellation(),因为该任务很长并且要经过许多函数。我想我可以完成我想要创建一个显式 Thread 的任务,但我真的很想避免手动线程管理。也就是说……

问题:是否有可能在任务被取消时自动抛出异常,如果没有,是否有任何好的替代方法(模式等)来减少使用 CancellationToken.ThrowIfCancellation() 污染代码?

我想避免这样的事情:

async Task<Bar> DoWork(Foo foo)
{
CancellationToken.ThrowIfCancellation()

await DoStuff1();

CancellationToken.ThrowIfCancellation()

await DoStuff2();

CancellationToken.ThrowIfCancellation()

await DoStuff3();
...
}

我觉得这个问题与this one 有很大不同因为我明确要求一种方法来最小化检查取消 token 的调用,接受的答案对此响应“时不时地,在函数内部,调用 token.ThrowIfCancellationRequested()”

最佳答案

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()?

没有,也没有。所有取消都是合作的。取消代码的最佳方式是让代码响应取消请求。这是唯一好的模式。

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

不是真的。

此时,问题是“如何取消不可取消的代码?”答案取决于您希望系统的稳定性:

  1. 在单独的Thread 中运行代码,并在不再需要时Abort 线程。这是最容易实现的,但在应用程序不稳定方面也是最危险的。坦率地说,如果您曾在应用中的任何位置调用 Abort,除了心跳/smoketest 检查等标准做法之外,您还应该定期重启该应用。
  2. 在单独的 AppDomain 中运行代码,并在不再需要该 AppDomain 时卸载。这更难实现(您必须使用远程处理),并且在 Core 世界中不是一个选项。事实证明,AppDomain 甚至没有像预期的那样保护包含应用程序,因此任何使用此技术的应用程序也需要定期重启。
  3. 在单独的进程中运行代码,并在不再需要时杀死该进程。这是实现起来最复杂的,因为您还需要实现某种形式的进程间通信。但它是取消不可取消代码的唯一可靠的解决方案

如果您放弃不稳定的解决方案 (1) 和 (2),那么唯一剩下的解决方案 (3) 就是的工作 - 方式,远远超过使代码可取消。

TL;DR:只需按照设计使用的方式使用取消 API。这是最简单有效的解决方案。

关于c# - 使用 CancellationToken 取消任务而不在任务中明确检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57171975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com