We're calling methods on an ActiveX component from within a WPF and STA application. This calling is late-bound performed via:

res = ocx.GetType().InvokeMember(methodName, flags, null, ocx, args);

...where ocx is the ActiveX object retrieved with the System.Windows.Forms.AxHost.GetOcx() method.

This call is performed from within a WPF event handler, say 'mouse clicked'.

Now the problem. If we double-click the 'mouse clicked' event will trigger, running InvokeMember(). However, during this call, we see that the 'mouse clicked' event is re-entered. So in the same thread, we see the event handler twice on the call stack. This is very unexpected, and we're trying to prevent that. How can we prevent this from happening?

The only reason we can think of why it happens is:

  • The COM object is created in another STA, so we're performing a cross-STA call which needs to be marshalled
  • cross-thread STA calls uses a Windows Message to send an RPC request to the COM component
  • cross-thread STA calls use the Windows Message pump to receive RPC answer
  • During the waiting another type of event comes in (like 'mouse clicked'), and this gets handled before the RPC answer gets handled.
  • This RPC answer gets handled

Things we tried to fix the problem:

  • use lock() in all event handlers. This does not work since lock() will lock a thread, and in this case it is the same thread which re-enters the event handler.
  • use custom locking like 'bool locked = false; if (!locked) { locked = true; InvokeMethod(); ...; locked = false; }'. This works partially: it throws away the events instead of queuing them for later, and need an extensive change to all our event handlers, which is not nice to do.
  • use Dispatcher.DisableProcessing to stop (other) messages from being processed. This does not help: it throws an exception becaus
Edit
Report