By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,365 Members | 1,360 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,365 IT Pros & Developers. It's quick & easy.

Com Interop Event blocked by WaitOne

P: n/a
I've got a (VC++ 6.0) com object which does something asynchronously (writes
a DVD image, actually).

It rasies COM events to indicate progress, including completion.

I've got this running in a c# application, with the events coming up and
being caught (The idea is to use this to Set a ManualResetEvent which will
alow the rest of the processign to happen).

However, when I put an event after the call to start the async process off,
the events seem never to be caught.

When the WaitOne times out, I get a whole swathe of debug prints from the
COM dll, but the Debug.WriteLine from the (COM) event handler are never
called.

Clearly it's some threading / synchronisation issue, but I've not found
anything obviously relevant in the docs or through google.

Can any one help, please?

Iain
Nov 15 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Hi,

As your application is most likely marked with [STAThread], the events
raised by the COM object are handled on the single UI thread your
application has. Once you block the UI thread with WaitOne(), it will never
be able to process further events from the COM object.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Iain" <id********@dircon.co.uk> wrote in message
news:Oe**************@tk2msftngp13.phx.gbl...
I've got a (VC++ 6.0) com object which does something asynchronously (writes a DVD image, actually).

It rasies COM events to indicate progress, including completion.

I've got this running in a c# application, with the events coming up and
being caught (The idea is to use this to Set a ManualResetEvent which will
alow the rest of the processign to happen).

However, when I put an event after the call to start the async process off, the events seem never to be caught.

When the WaitOne times out, I get a whole swathe of debug prints from the
COM dll, but the Debug.WriteLine from the (COM) event handler are never
called.

Clearly it's some threading / synchronisation issue, but I've not found
anything obviously relevant in the docs or through google.

Can any one help, please?

Iain


Nov 15 '05 #2

P: n/a
Thanks Dmitriy.

But what do I DO?

Obviously the com dll is mutlithreaded ('both'). I've been trying to find
something on this attribute in the docs but haven't hit anything I find
particularly useful. Nor with MTAThread which is what I presume I should
use.

The test program is a windows forms program and I've changed the attribute
on Main() to [MTAThread] which has made no difference. I've also changed
the attributes of the methods that seem relevant (and the event handler) in
my class that does all the work - also to no avail.

Lastly, I've replaced the wait with a sleep loop. which I would have
thought would stand some chance of working. but no.

Sorry. still stuck.

Iain

"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:OQ**************@TK2MSFTNGP09.phx.gbl...
Hi,

As your application is most likely marked with [STAThread], the events
raised by the COM object are handled on the single UI thread your
application has. Once you block the UI thread with WaitOne(), it will never be able to process further events from the COM object.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Nov 15 '05 #3

P: n/a
I've put a bit of debug code just before the creation of the Com object (and
after the invocation of thee method in the Com object) and the Thread at
those points is MTA.

So it looks like the problem is elsewhere.

The underlying COM object has been coded to work in VB 6 which means that
the events are raised from the main thread (basically the worker thread
sends the event information into a Windows Message loop owned by COM Object.
when this is received it raises the event). So the events are effectively
marshalled on to the initiating thread.

The thread which is doing the writing does not seem visible in the .NET IDE,
however it does continue to operate even after I break the c# stuff.

Iain
"Iain" <id********@dircon.co.uk> wrote in message
news:uG**************@tk2msftngp13.phx.gbl...
Thanks Dmitriy.

But what do I DO?

Obviously the com dll is mutlithreaded ('both'). I've been trying to find
something on this attribute in the docs but haven't hit anything I find
particularly useful. Nor with MTAThread which is what I presume I should
use.

The test program is a windows forms program and I've changed the attribute
on Main() to [MTAThread] which has made no difference. I've also changed
the attributes of the methods that seem relevant (and the event handler) in my class that does all the work - also to no avail.

Lastly, I've replaced the wait with a sleep loop. which I would have
thought would stand some chance of working. but no.

Sorry. still stuck.

Iain

"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:OQ**************@TK2MSFTNGP09.phx.gbl...
Hi,

As your application is most likely marked with [STAThread], the events
raised by the COM object are handled on the single UI thread your
application has. Once you block the UI thread with WaitOne(), it will

never
be able to process further events from the COM object.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE


Nov 15 '05 #4

P: n/a
You can try the following. In the .NET application, launch a separate thread
that would only wait for an event. When the event is set, this thread would
notify the main thread by invoking some method through Form.Invoke() and
immediately exit.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Iain" <id********@dircon.co.uk> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
I've put a bit of debug code just before the creation of the Com object (and after the invocation of thee method in the Com object) and the Thread at
those points is MTA.

So it looks like the problem is elsewhere.

The underlying COM object has been coded to work in VB 6 which means that
the events are raised from the main thread (basically the worker thread
sends the event information into a Windows Message loop owned by COM Object. when this is received it raises the event). So the events are effectively
marshalled on to the initiating thread.

The thread which is doing the writing does not seem visible in the .NET IDE, however it does continue to operate even after I break the c# stuff.

Iain
"Iain" <id********@dircon.co.uk> wrote in message
news:uG**************@tk2msftngp13.phx.gbl...
Thanks Dmitriy.

But what do I DO?

Obviously the com dll is mutlithreaded ('both'). I've been trying to find something on this attribute in the docs but haven't hit anything I find
particularly useful. Nor with MTAThread which is what I presume I should use.

The test program is a windows forms program and I've changed the attribute on Main() to [MTAThread] which has made no difference. I've also changed the attributes of the methods that seem relevant (and the event handler)

in
my class that does all the work - also to no avail.

Lastly, I've replaced the wait with a sleep loop. which I would have
thought would stand some chance of working. but no.

Sorry. still stuck.

Iain

"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote in message news:OQ**************@TK2MSFTNGP09.phx.gbl...
Hi,

As your application is most likely marked with [STAThread], the events
raised by the COM object are handled on the single UI thread your
application has. Once you block the UI thread with WaitOne(), it will

never
be able to process further events from the COM object.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE




Nov 15 '05 #5

P: n/a
Hmm. I'm trying to get my head round this (sorry, I've taken some time out
to do some higher level stuff, now back to the detail).

Basically, this will end up as a server process - possibly a service, so I
can't rely on UI level stuff like timers of Form.Invoke.

I've taken the waitforone out as an experiment and also the stuff that's
meant to follow afterwards (leaving the code to return to the test UI) and
the events come through fine.

I've tried setting the process of on another thread, but that failed.
Reasonably enough as I guess the thread that could receive the messages is
still locked and therefore will not peek the equivalent of a message loop
(which seems to be the essential problem) - I am by the way, reasonbly
convinced that I could have done this in unmanaged C++ 6 without this class
of problem, though in truth I haven't tried it.

I can't actually see any way of setting of a thread which just waits for the
events. If I block it, it wont get the events, if I don't block it it will
just exit. As mentioned I've tried putting a sleep loop in an it STILL
doesn't get teh events.

What I seem to need is some kind of 'yeild' or message loop functionality.
Is there such - not obvious to a quick look.

This seems an unlikley deficiency in dot net. What am I missing?

Iain
"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:Op**************@TK2MSFTNGP11.phx.gbl...
You can try the following. In the .NET application, launch a separate thread that would only wait for an event. When the event is set, this thread would notify the main thread by invoking some method through Form.Invoke() and
immediately exit.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

Nov 15 '05 #6

P: n/a
Iain,

I'd suggest receiving *COM* events on the main thread that should never be
blocked. To make the worker thread wait, introduce an AutoResetEvent that
the worker thread would wait for. Thus, the worker thread will be sleeping
until the AutoResetEvent is signaled. And after the event is signaled, the
worker thread will do some useful work and go to sleep until the
AutoResetEvent is signaled for the next time.

The main thread, in turn, will be signaling the AutoResetEvent every time it
receives a COM event. If you need to pass some params to the worker thread
before it starts its work, introduce a thread-safe parameter object
accessible to both threads.

Or, and it might be even better! - you can employ the ThreadPool. Every time
the main thread receives a COM event, it queues a work item on the thread
pool, thus avoiding any "home-made" thread care.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Iain" <id********@dircon.co.uk> wrote in message
news:eG**************@TK2MSFTNGP09.phx.gbl...
Hmm. I'm trying to get my head round this (sorry, I've taken some time out to do some higher level stuff, now back to the detail).

Basically, this will end up as a server process - possibly a service, so I
can't rely on UI level stuff like timers of Form.Invoke.

I've taken the waitforone out as an experiment and also the stuff that's
meant to follow afterwards (leaving the code to return to the test UI) and
the events come through fine.

I've tried setting the process of on another thread, but that failed.
Reasonably enough as I guess the thread that could receive the messages is
still locked and therefore will not peek the equivalent of a message loop
(which seems to be the essential problem) - I am by the way, reasonbly
convinced that I could have done this in unmanaged C++ 6 without this class of problem, though in truth I haven't tried it.

I can't actually see any way of setting of a thread which just waits for the events. If I block it, it wont get the events, if I don't block it it will just exit. As mentioned I've tried putting a sleep loop in an it STILL
doesn't get teh events.

What I seem to need is some kind of 'yeild' or message loop functionality.
Is there such - not obvious to a quick look.

This seems an unlikley deficiency in dot net. What am I missing?

Iain
"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:Op**************@TK2MSFTNGP11.phx.gbl...
You can try the following. In the .NET application, launch a separate

thread
that would only wait for an event. When the event is set, this thread

would
notify the main thread by invoking some method through Form.Invoke() and
immediately exit.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE



Nov 15 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.