Thread.Abort()方法冻结

所以我用AbortException搜索它因为使用不安全的代码而冻结,并且只有当控制流返回到托管代码时AbortException抛出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()它。 不会造成任何损害,整个过程状态都会被丢弃。 恢复往往非常棘手,但是,您仍然需要重新启动进程并将其恢复到原始状态。 特别是国家恢复通常很难可靠地完成。