COM Interop and ManualResetEVents

I

Iain

I raised this a few days ago and Dmitriy helped, but there's been a lot of
posts under the bridge since then so I thought I'd start afresh.

Basically, I have a COM Dll written in C++ (6). It's job is to create DVD
Images which it does nicely. It runs Asynchronously. That is (once all the
information is provided) it starts its own thread and raises events as
things develop.

The events are marshalled through a hidden window to so that they aways call
back on the thread which created the object. This is a requirement for them
to run in an STA like VBs.

I've added this to my c# project and hooked the events. When I want to
create the image I call the method on my COM object and the wait for a
manualResetEvent to be set. This should be done by the com event handler,
but it does not.

When the WaitFor times out all the events that should have happened suddenly
come through (by this time the thread has returned control the Windows Forms
test program).

If I use a loop with Sleeps the same thing happens.

I've tried with the the thread marked as STA and MTA - no difference. I've
put the call to the main com method on a separate thread. Still doesn't
work.

The only way I can get it to work is by returning control to the UI.

Now the good book says in 'Managed and Unmanaged Threading in Microsoft
Windows'

That WaitHandle (and it's descendents) ... all these managed blocking
operations will correctly pump messages in your apartment while your thread
is blocked.

This seems not to be the case.

Dmitry suggesting putting the Event handlers on another thread, but to be
truthful I dont see how I can do that without some sort of blocking which
seems to stop the events being received!

I also wonder if it's something to do with the events being forced to come
back on the thread which created them. Perhaps this is NOT the thread as it
appears in c#? (The Com object is marked as both. I suppose I could try
de-marshalling the events and see if that helps - will break it in VB
though!)

This system will eventually sit inside a service, so the obvious answer of
writing it with Timers and state variables and a Windows Form is not ideal.

Any ideas (and thankyou)?

Iain
 
I

Iain

Well. For anyone that wants to know, demarshalling the events in the COM
object allowed the events to be seen during the WaitOne of the
ManualResetEvent.

Basically, in the COM dll the events were (largely) raised on a seperate
thread than the one which created the object. In order to work with VB
(which is single threaded) you have to Post a Windows Message to a hidden
window. This is picked up by the Message Pump of the hidden window (which
runs on the main thread) and you then raise the event.

So I've taken that bit out. Now I raise the event directly in the thread
which causes the event.

Now these events are received during the Wait state of the C# program and it
does the setting of the events and it all works nicely.

It works with the c# thread marked as MTA and it works with the c# thread
marked as MTA.

If any MS support people read this thread, it seems to me that this is an
appropriate subject for a knowledge base article.

OH - and I'd LOVE to know why this happens!

This sort of stuff is NOT obvious - though I must admit that mutlithreaded
com objects which raise events, are meant for VB and now want to be used in
c# are *probably* not around in their masses.

Iain
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top