Thread.Abort()方法冻结

问题描述 投票:0回答:1

所以我用谷歌搜索它因为使用不安全的代码而冻结,并且只有当控制流返回到托管代码时才会抛出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方式,它非常复杂。

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

c# .net multithreading reflection appdomain
1个回答
9
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.