c#为什么不支持中断任务
本文关键字:任务 中断 不支持 为什么 | 更新日期: 2023-09-27 18:12:09
线程支持中断。为什么Task不能?
从我的(不知情的)角度来看,允许Task支持中断似乎是合理的:
- 如果任务当前没有在线程上执行,调用Task . interrupt()将设置TaskInterruptException,当任务被调度时抛出。
- 否则,将在执行任务的线程中抛出TaskInterrupException,该异常将在任务中捕获或添加到顶部的AggregateException。我猜这个功能需要任务知道正在执行的线程(这是不合理的吗?)
实现该特性所需的部分是否已经存在,还是需要对语言实现进行更改?
添加:我读过很多关于SO的问题,讨论杀死/中止任务,以及他们讨论CancellationToken
和(不鼓励的)Thread.Abort
方法的相关答案。
在我自己的摆弄中,我发现注册线程。用CancellationToken中断。Register不中断在任务中运行的线程,而是中断在令牌上调用cancel的线程。
所以,在我看来,仍然需要一个认可的功能,允许开发人员确保任务可以(轻轻地)终止。
我还将补充(以免有人说"重写你的任务以接受CancellationTokens"),该功能在开发人员不拥有而不拥有在任务中执行的代码的情况下特别有价值。
而且,从原则上讲,似乎应该有一种方法让Task的执行者能够提供取消的保证,而不是依赖于Task的实现者使用取消令牌来正确地做事情。
另一个补充:不考虑风险,c# API支持Thread.Abort
和Thread.Interrupt
。所以我的问题是,从本质上讲,为什么Task
不支持相同的API(具有相同的固有风险)?
这个帖子被标记为这个问题的副本。然而,在发布这个问题(和所有的答案)之前,我已经阅读了参考问题-这个问题不是重复的,而是一个相关的问题寻求额外的信息。这个问题问的是"你能中止吗",而答案本质上是"你不应该中止"——我的问题是"既然中断比中止好,为什么中断不被支持?"是什么机制障碍阻碍了这一功能?"根据这个问题,中断和终止线程之间有重要的区别,并且这种中断更受欢迎。
而且,从原则上讲,似乎应该有一种方法让Task的执行者能够提供取消的保证,而不是依赖于Task的实现者使用取消令牌来正确地做事情。
我不同意这种说法。任何硬操作都有很高的风险使你的系统处于待定状态,在这种状态下,它不能继续正常工作,特别是当你试图中止那些不属于你的代码的任务时。
所以优雅地取消任务是避免这种情况的唯一方法。您是希望生产中的系统(设计为全天候运行)泄漏资源并意外崩溃,还是希望在无法取消不占用CacnellationToken
的Task
时浪费一些额外的资源和时间?
这是我的个人观点,我发现Task.Abort()
在大多数情况下是有害的而不是有用的。
EDIT:此外,Task
只是操作的句柄,您可以在任何线程上创建TaskCompletionSource<T>
并在任何时间点设置完成,因此不可能跟踪实际运行Task
背后逻辑代码的线程。例如,Task.WhenAll(Task[])
返回Task
。你将如何中止它?它不是在任何线程上运行,而是在给定任务完成时侦听。也就是说,添加一个通用的Abort方法在技术上是不可行的。