dasheddot
dasheddot

Reputation: 2966

How to handle blocking synchronous external DLL methods

Recently I worked with an external dll library where I have no influence on it. Under some special circumstances, a method of this third party dll is blocking and never returning.

I tried to work around this issue by executing this method in a new AppDomain. After a custom timeout, I wanted to Unload the AppDomain and kill all this crap ;)

Unfortunately, it does not work - as someone would expect.

After some time it throws CannotUnloadAppDomainException since the blocking method does not allow aborting the thread gracefully.

I depend on using this library and it does not seem that there will be an update soon.

So can I work around this issue, even if it's not best practice? Any bad hack appreciated :)

Upvotes: 3

Views: 1222

Answers (3)

Hans Passant
Hans Passant

Reputation: 941705

An AppDomain cannot typically solve that problem, it's only good to throw away the state of your program. The real issue is that your thread is stuck. In cases like these, calling Thread.Abort() is unlikely to work, it will just get stuck as well. A thread can only be aborted if it is a "alertable wait state", blocking on a CLR synchronization object. Or executing managed code. In a state that the CLR knows how to safely clean up. Most 3rd party code falls over like this when executing unmanaged code, no way to ever clean that up in a safe way. A decisive hint that this is the case is AppDomain.Unload failing to get the job done, it can only unload the AppDomain when it can abort the threads that are executing code in the domain.

The only good alternative is to run that code in a separate process. Which you can kill with Process.Kill(). Windows do the cleanup. You'd use a .NET interop mechanism to talk to that code. Like named pipes, sockets, remoting or WCF. Plus the considerable hassle of having to write the code that can detect the timeout, kills the process, starts it back up and recovers internal state since you now restart with an uninitialized instance of that 3rd party code.

Do not forget about the real fix. Create a small repro project that reproduces the problem. When it hangs, create a minidump of the process. Send both to the 3rd party support group.

Upvotes: 6

wal
wal

Reputation: 17739

after reading this (scroll down the end to Blocking Issues) I think your only solution is to run the method in a different process - this might involve quite a bit of refactoring and/or a 'host' project (eg Console application) that loads the method in question and makes it easy to call (eg reading args from command line) when launching the new process using the Process class

Upvotes: 3

Murtuza Kabul
Murtuza Kabul

Reputation: 6514

You can always use background worker, no need to create a new appdomain. This will ensure that you have complete control over the execution of the thread.

However, there is no way to ensure that you can gracefully abort the thread. As the dll is unmanaged, chances are there that it may cause memory leaks. However, spawning a new thread will ensure that your application does not crash when the Dll does not respond.

Upvotes: 1

Related Questions