Question

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.

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' . 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();

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

Does a superficial solution exist?

Was it helpful?

Solution

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.

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.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top