Is an STA Message Loop required in this case?

I have some COM objects that I create and run in threads in a .NET application. Streams are marked as Single Threaded Apartments and everything seems to be working. I understand that if these threads try to access COM objects from the main thread, then these objects will be automatically marshaled and serialized for me in .NET, so even in this case everything will be processed for me, everything is safe and neat, although it is possible a little slow.

My question is that everything is working fine, I am not pumping a cycle of messages in the STA flows that I create. I would prefer to avoid the message loop if I could, due to additional complications that it might cause (and possible loss of efficiency).

I read a bunch of tips on why a message loop is needed (mainly from the very useful Hans Passant), and I understand that a message loop gives a place in thread A, where another thread B may be requested, that the COM objects living on thread A can be marshaled and reproduced. If this is correct, then until no other threads request any of the COM objects in thread A, is Thread A safe in that it does not inflate the message loop? Or are there other cases where a message loop may also come into play?

Am I playing with fire here? And is there ever a case when you ask whether you play with fire, but you do not?

+2
multithreading com sta
May 18 '12 at 14:02
source share
2 answers

The STA contract requires pumping the message pipeline. But yes, trouble can be avoided. There are two main things that can go wrong:

  • Any call made using the interface method from another apartment, including another STA stream or a stream in the MTA, will not be completed. It looks like a dead end in your program, the call simply does not return. Remember that you can manage your calls well, but you don’t know what the COM component does. He can start the flow itself. You can see this in the debugger using Debug + Windows + Threads. Make sure that you run the debugger in unmanaged mode, and you can consider all the threads that you see. Not particularly easy btw.

  • The multicomponent COM components included in the delivery package expect that the message cycle will take care of its needs. It can be something harmless, like a timer, it will not tick when there is no cycle. Or he can do marshaling domestically. Use Spy ++ and check if there are hidden windows that belong to your new STA stream, a sign of a problem if you see it. A diagnosis is a component that simply behaves badly. Not raising events is a common setback.

Nothing can cling to the wall when you do not know enough about the internal functions of the server. Remember to check it out.

+3
May 19 '12 at 12:43 a.m.
source share

COM calls can be marshaled without a message pipeline.

When your STA thread waits for something, in most cases it automatically processes any pending COM calls.

The documentation for Thread.Join says Blocks the calling thread [...] while continuing to perform standard COM and SendMessage pumping.

The same thing happens for many other functions called on your behalf (CoWaitForMultipleHandles, etc.), for example. when your thread is waiting for input / output.

+1
May 18 '12 at 19:25
source share



All Articles