Thread.Abort() 方法冻结 [英] Thread.Abort() method freezes

查看:35
本文介绍了Thread.Abort() 方法冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在谷歌上搜索它因为使用不安全的代码而冻结,并且 AbortException 仅在控制流返回到托管代码时抛出.所以,就我而言,我有一个本地库,在线程中调用.所以有时我无法中止它,因为库是原生的,并且 Abort 方法不仅什么都不做,而且冻结了调用线程.

So I've googled that it freezes because of using unsafe code, and AbortException throws only when control flow returns to managed code. So, in my case I have a native library, called in a thread. So sometimes I can't abort it, because the library is native and the Abort method not just do nothing, but freezes the calling thread.

所以,我想解决它.

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

For example, using a different process should help, but it's very complicated.

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

So, a less heavy solution is to use ' AppDomains' . But anyway I should create an exe and call it. I tried to generate it in memory like this

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 方式,它非常非常复杂.

but I found only EMIT-way, it's very very complicated.

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

Does a superficial solution exist?

推荐答案

这不能正常工作.CLR 对于可以安全中止的代码类型有非常 严格的规定.重要的是,除了不明智地使用 Thread.Abort() 之外,在很多情况下 CLR 必须 中止代码,AppDomain 卸载是最重要的.

This cannot work by design. The CLR has very strict rules about what kind of code can safely be aborted. It is important, beyond the unwise use of Thread.Abort(), plenty of cases where the CLR must abort code, AppDomain unloads being foremost.

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

The iron-clad rule is that the CLR must be convinced that it is safe to abort the code. It is only convinced of that if the thread is busy executing managed code or is waiting on a managed synchronization object. Your case does not qualify, no way for the CLR to have any idea what that native code is doing. Aborting a thread in such a state almost never not causes problems. Same idea of the danger of Thread.Abort() but multiplied by a thousand. A subsequent deadlock on an internal operating system lock is very likely, utterly undebuggable.

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

An AppDomain therefore is not a solution either, it cannot be unloaded until the thread stopped running and it won't.

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

Only thing you can do is isolate that code in a separate process. Write a little helper EXE project that exposes its api through a standard .NET IPC mechanism like a socket, named pipe, memory mapped file, remoting or WCF. When the code hangs, you can safely Process.Kill() it. No damage can be done, the entire process state is thrown away. Recovering tends to be quite tricky however, you still do have to get the process restarted and get it back into the original state. Especially the state restoration is usually very difficult to do reliably.

这篇关于Thread.Abort() 方法冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆