线程支持中断。为什么不执行任务?
从我(不知情)的角度来看,允许Task支持中断似乎是合理的:
实现此功能所需的部分是否已经存在,或者是否需要更改语言实现?
增加:
我已经阅读了很多关于SO的问题,讨论杀死/中止任务,以及相关的答案,讨论CancellationToken
和(气馁的)Thread.Abort
方法。
在我自己的小提琴中,我发现使用CancellationToken.Register注册Thread.Interrupt不会中断任务中运行的线程,而是中断对令牌的调用取消的线程。
因此,正如我所看到的,仍然需要一个受制裁的功能,允许开发人员确保任务可以(轻轻地)终止。
我还会添加(以免有人说“重写你的任务以取消取消取消”),在开发人员不拥有在任务中执行的代码的情况下,此功能特别有用。 。
而且,就原则问题而言,似乎应该有一种方法让任务的执行者能够提供取消的保证,而不是依赖于任务的实施者来做正确的取消令牌。
另外一个补充:
无论风险如何,C#API都支持Thread.Abort
和Thread.Interrupt
。所以我的问题基本上是为什么Task
不支持相同的API(具有相同的固有风险)?
更新
此帖子已被标记为this question的副本。但是,在发布此问题(以及所有答案)之前,我已经阅读了引用的问题 - 这个问题不是重复的,而是一个寻求其他信息的相关问题。那个问题问“你能不能中止”而答案基本上是“你不应该中止” - 我的问题是“鉴于中断比中止更好,为什么不中断支持的功能?什么机械障碍禁止这个功能?”。根据{{3}},中断和中止线程之间存在重要差异,并且该中断更受欢迎。
答案 0 :(得分:1)
而且,就原则问题而言,似乎应该有一种方法让任务的执行者能够提供取消的保证,而不是依赖于任务的实施者来做正确的取消令牌。
我不同意这种说法。任何困难都有很高的风险让你的系统处于未确定的状态,它不能继续正常运行,特别是如果你试图中止你不拥有的代码的任务。
如此设计的优雅取消任务是避免此类情况的唯一方法。您是否更喜欢生产中的系统(设计为24/7全天候运行)以泄漏资源并意外崩溃,或者只是在您无法取消Task
时浪费一些额外的资源和时间不接受CacnellationToken
?
这是我个人的意见,在大多数情况下,我发现Task.Abort()
对有害而非有用。
编辑:此外,Task
只是操作的句柄,您可以创建TaskCompletionSource<T>
并在任何线程上的任何时间点设置完成,因此,无法追踪Task
背后的逻辑代码实际运行的线程。例如,Task.WhenAll(Task[])
会返回Task
。你怎么会中止那个?它没有在任何线程上运行,而是在完成给定任务时进行侦听。即添加一般的Abort方法在技术上是不可行的。