Thread.Abort()方法冻结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thread.Abort()方法冻结相关的知识,希望对你有一定的参考价值。

所以我用谷歌搜索它因为使用不安全的代码而冻结,并且只有当控制流返回到托管代码时才会抛出AbortException。所以,在我的情况下,我有一个本机库,在一个线程中调用。所以有时我不能中止它,因为库是本机的,而Abort方法不仅不做任何事情,而是冻结调用线程。

所以,我想解决它。

例如,使用不同的过程应该有所帮助,但它非常复杂。

因此,一个不太重的解决方案是使用'AppDomains'。但无论如何我应该创建一个exe并调用它。我试着像这样在内存中生成它

var appDomain = AppDomain.CreateDomain("newDomain");
var assemblyBuilder = appDomain.DefineDynamicAssembly(new AssemblyName("myAsm"), AssemblyBuilderAccess.RunAndCollect);
var module = assemblyBuilder.DefineDynamicModule("myDynamicModule");
var type = module.DefineType("myStaticBulder", TypeAttributes.Public);
var methBuilder = type.DefineMethod("exec", MethodAttributes.Static | MethodAttributes.Public);
var ilGenerator = methBuilder.GetILGenerator();

但我发现只有EMIT方式,它非常复杂。

是否存在肤浅的解决方案?

答案

这在设计上是行不通的。 CLR对可以安全地中止哪种代码有非常严格的规定。重要的是,除了不明智地使用Thread.Abort()之外,CLR必须中止代码的大量情况,AppDomain卸载是最重要的。

铁腕规则是CLR必须确信中止代码是安全的。只有当线程忙于执行托管代码或正在等待托管同步对象时才会确信。您的案例不符合条件,CLR无法知道本机代码在做什么。在这种状态下中止线程几乎不会导致问题。同样认为Thread.Abort()的危险但乘以一千。内部操作系统锁定的后续死锁很可能是完全不可取的。

因此,AppDomain也不是解决方案,它在线程停止运行之前无法卸载,也不会。

您唯一能做的就是在单独的进程中隔离该代码。编写一个小助手EXE项目,通过标准的.NET IPC机制(如套接字,命名管道,内存映射文件,远程处理或WCF)公开其api。当代码挂起时,您可以安全地Process.Kill()它。不会造成任何损害,整个过程状态就会被抛弃。恢复往往非常棘手,但是,您仍然需要重新启动进程并将其恢复到原始状态。特别是状态恢复通常很难可靠地完成。

以上是关于Thread.Abort()方法冻结的主要内容,如果未能解决你的问题,请参考以下文章

.NET Thread.Abort 再次

可以像中止一个Thread(Thread.Abort方法)一样中止一个Task吗?

Thread.Abort 方法

c# .net 一条线程 abort 之后,怎么重启启动。

C# - 线程中止异常(Thread Abort Exception)重新抛出自身

Thread.Abort() 并在 finally 之后延迟