【发布时间】:2016-10-07 23:05:57
【问题描述】:
线程支持中断。为什么没有任务?
从我(不知情的)角度来看,允许 Task 支持中断似乎是合理的:
- 如果任务当前没有在线程上执行,调用 task.Interrupt() 将设置一个 TaskInterruptException,以便在计划任务时抛出。
- 否则,TaskInterrupException 将在执行任务的线程中抛出,该异常将在任务中捕获或添加到顶部的 AggregateException。我猜这个功能需要任务知道正在执行的线程(这不合理吗?)
实现此功能所需的部分是否已经存在,或者这是否需要更改语言实现?
补充:
我已经阅读了许多关于 SO 的问题,这些问题讨论了杀死/中止任务,其相关答案讨论了 CancellationToken 和(不鼓励的)Thread.Abort 方法。
在我自己的摆弄中,我发现用 CancellationToken.Register 注册 Thread.Interrupt 并不会中断任务中运行的线程,而是会中断对令牌调用取消的线程。
因此,在我看来,仍然需要一个经过批准的功能,允许开发人员确保可以(温和地)终止任务。
我还将补充(以免有人说“重写您的任务以获取 CancellationTokens”)此功能在开发人员确实不拥有任务中正在执行的代码的情况下特别有价值.
而且,从原则上讲,似乎应该有一种方法让任务的执行者能够提供取消的保证,而不是依赖任务的实施者通过取消来正确地做事令牌。
另一个补充:
不管风险如何,C# API 都支持Thread.Abort 和Thread.Interrupt。所以我的问题是,本质上,为什么Task 不支持相同的 API(具有相同的固有风险)?
更新
该帖子已被标记为与this question 重复。但是,在发布这个问题(以及所有答案)之前,我已经阅读了引用的问题 - 这个问题不是重复的,而是一个寻求更多信息的相关问题。这个问题问“你能中止吗”,答案基本上是“你不应该中止”——我的问题是“鉴于中断比中止更好,为什么不中断受支持的功能?哪些机械障碍禁止此功能?”。根据this question 的说法,中断和中止线程之间存在重要区别,并且更倾向于使用中断。
【问题讨论】:
-
谢谢你的链接,汉斯。你在那里讨论 Thread.Abort。 Thread.Interrupt 也一样吗?我知道 Thread.Interrupt 应该避免在讨厌的位置抛出异常。
-
另外,不管有什么风险,API 仍然支持 Thread.Abort 和 Thread.Interrupt。我的问题是为什么不支持相同的任务?
-
如果您认为需要中止第三方代码,那么您确实必须在单独的应用程序域或进程中运行该代码。这是彻底中止的唯一方法。否则你应该使用合作取消模型。