简体   繁体   English

Thread.Abort()方法冻结

[英]Thread.Abort() method freezes

So I've googled that it freezes because of using unsafe code, and AbortException throws only when control flow returns to managed code. 因此,我用Google搜索它由于使用不安全的代码而冻结,并且AbortException仅在控制流返回到托管代码AbortException抛出。 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. 所以有时候我无法中止它,因为该库是本机的,并且Abort方法不仅不执行任何操作,而且冻结了调用线程。

So, I'd like to solve it. 所以,我想解决它。

For example, using a different process should help, but it's very complicated. 例如,使用其他过程应会有所帮助,但这非常复杂。

So, a less heavy solution is to use ' AppDomains' . 因此,较不繁重的解决方案是使用“ AppDomains”。 But anyway I should create an exe and call it. 但是无论如何,我应该创建一个exe并调用它。 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();

but I found only EMIT-way, it's very very complicated. 但是我发现只有EMIT方式,这非常非常复杂。

Does a superficial solution exist? 是否存在表面解决方案?

This cannot work by design. 这不是设计使然。 The CLR has very strict rules about what kind of code can safely be aborted. CLR对于可以安全中止哪种代码有非常严格的规则。 It is important, beyond the unwise use of Thread.Abort(), plenty of cases where the CLR must abort code, AppDomain unloads being foremost. 重要的是,除了不明智地使用Thread.Abort()之外,在许多情况下CLR 必须中止代码,AppDomain最重要的是卸载。

The iron-clad rule is that the CLR must be convinced that it is safe to abort the code. 硬性规定是必须使CLR确信中止代码是安全的。 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. 您的情况符合,没有办法为CLR有任何的想法是什么本地代码在做什么。 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. 关于Thread.Abort()的危险的想法相同,但是乘以一千。 A subsequent deadlock on an internal operating system lock is very likely, utterly undebuggable. 内部操作系统锁上的后续死锁很有可能,而且完全不可言喻。

An AppDomain therefore is not a solution either, it cannot be unloaded until the thread stopped running and it won't. 因此,AppDomain 也不是解决方案,它只能在线程停止运行并且无法运行之前才能卸载。

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. 编写一个帮助程序EXE小项目,该项目通过标准.NET IPC机制(例如套接字,命名管道,内存映射文件,远程处理或WCF)公开其api。 When the code hangs, you can safely Process.Kill() it. 代码挂起后,可以安全地对其进行Process.Kill()处理。 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. 尤其是状态恢复通常很难可靠地完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM