Thread resistance in the critical finalizer

We are working with a third party legacy system that requires thread merging for some crash logic. We also have a WCF service inside IIS which, under heavy loads, will do a rough offload on our application domain. In these cases, the critical finalizer performs cleanup. Unfortunately, no thread binding in the finalizer, third party systems deadlock.

So rude:

public class FooEnvironment : CriticalFinalizerObject, IDisposable
{
  public FooEnvironment()
  {
    // start up C API
  }

  public bool Dispose()
  {
    // shutdown C API (from same thread ctor was called on)
  }

  ~FooEnvironment()
  {
    // try to shutdown C API but deadlock!
  }
}

      

I've tried various things in which we run the ExecutionContext from the init thread, but that doesn't work (at least in IIS) and we get an invalid operation stating that this execution context cannot be used (ostensibly because it is possibly was attacked via AppDomains, which seems likely).

I read a few things, mostly stating that what I am trying to do cannot be done, but I figured I would ask as there is not much information on this thread.

+3


source to share


1 answer


In the old days I developed a library that wrapped the hideous DDEML which is a Win32 api wrapper around the DDE protocol. DDEML has thread affinity requirements, so I can feel your pain.

The only strategy that will work is to create a dedicated thread that makes all your library calls. This means biting the marker and marching every single request to call that API on that dedicated thread, then fetch the result back to the original thread. It sucks and is slow, but it's the only method that's guaranteed to work.



It can be done, but it hurts. You can see how I solved the problem in my NDde library . Basically, the finalizer simply dispatches a message via static method calls to a thread that can receive and send them to the appropriate API call. In my case, I created a thread that called Application.Run

to listen for messages because DDE required the Windows message loop anyway. In your case, you will want to create a thread in such a way as to keep track of the message queue. It is not difficult if you are using a class BlockingCollection

, because the method Take

blocks until the item appears in the queue.

+1


source







All Articles