0

0

c# Thread.Interrupt 和 Thread.Abort 的区别和废弃原因

星降

星降

发布时间:2026-01-18 12:03:02

|

247人浏览过

|

来源于php中文网

原创

Thread.Interrupt()仅对WaitSleepJoin状态有效,因它只在Thread.Sleep、Join、Monitor.Wait等阻塞时抛出ThreadInterruptedException;计算中调用无效。

c# thread.interrupt 和 thread.abort 的区别和废弃原因

Thread.Interrupt 为什么只对 WaitSleepJoin 状态有效

Thread.Interrupt() 不是“强行叫醒任意线程”,它只在目标线程处于阻塞等待状态(即 ThreadState.WaitSleepJoin)时才起作用。比如线程正在执行 Thread.Sleep(1000)thread.Join()Monitor.Wait()lock 内部等待时,调用 Interrupt() 会让它立即跳出阻塞,并抛出 ThreadInterruptedException 异常。

如果线程此刻正在做纯计算(比如循环累加、字符串拼接),Interrupt() 调用不会中断执行,也不会抛异常,更不会改变线程状态——它就像没发生过一样。

  • 常见错误现象:调用 thread.Interrupt() 后线程毫无反应 → 很可能它根本不在等待状态
  • 必须配合 try-catch (ThreadInterruptedException) 捕获并退出逻辑,否则异常未处理会终止线程
  • 它不终止线程,只“中断等待”,后续代码仍会继续运行(除非你主动 return 或 throw)

Thread.Abort 已被彻底废弃且危险

Thread.Abort() 在 .NET Framework 时期就已被标记为“不推荐使用”,到 .NET Core / .NET 5+ 中**完全移除**——编译直接报错:'Thread.Abort()' is obsolete。它会向目标线程注入 ThreadAbortException,强制撕开整个调用,跳过 finally 块(除非显式调用 Thread.ResetAbort(),但该方法也已废弃)。

  • 资源泄露高发:文件句柄、数据库连接、锁未释放就退出
  • 状态不一致:对象可能处于半初始化或半销毁状态
  • 无法跨平台:.NET Core 不支持 Thread.Abort(),连反射绕过都失败
  • 现代替代方案只有 CancellationToken,没有“安全的 Abort”这种东西

为什么 CancellationToken 是唯一推荐路径

所有新代码中,Thread.Interrupt()Thread.Abort() 都不该出现。取而代之的是基于协作取消的 CancellationToken 机制,它和 Taskasync/awaitParallel.ForEachAsync 等深度集成,支持非阻塞轮询、超时、父子令牌关联、取消注册回调等能力。

AI at Meta
AI at Meta

Facebook 旗下的AI研究平台

下载

例如:

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
try
{
    await SomeLongRunningOperationAsync(cts.Token);
}
catch (OperationCanceledException) when (cts.Token.IsCancellationRequested)
{
    // 清理资源,优雅退出
}
  • CancellationToken 不依赖线程状态,计算密集型循环里也能每轮检查 token.ThrowIfCancellationRequested()
  • 第三方库(如 HttpClient、EF Core)原生支持 CancellationToken,无需自己封装中断逻辑
  • 无法“强制终止”是设计使然——现代并发模型拒绝粗暴中断,只接受协作退出

遗留 Thread 代码迁移要注意什么

如果你维护老项目,还看到 Interrupt()Abort(),别只是注释掉,要重构取消逻辑。重点不是“怎么让旧方法继续跑”,而是“怎么把取消信号传进业务逻辑里”。

  • Thread.Sleep() 替换为 await Task.Delay(ms, token)
  • while (!done) { ... } 改成 while (!token.IsCancellationRequested) { ... }
  • 避免在 Thread 构造函数里传入无取消支持的长耗时方法;改用 Task.Run(() => ..., token)
  • 后台线程若需响应取消,请用 Task.Factory.StartNew(..., token) 而非裸 new Thread(...).Start()

真正难的不是写对 CancellationToken,而是把原本隐含在线程生命周期里的“该停就停”语义,显式地、可测试地、可组合地表达出来——这一步漏了,哪怕用了 CancellationToken,取消也可能失效。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

89

2023.09.25

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6095

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

806

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1062

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1244

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.9万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号