Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
364 views
in Technique[技术] by (71.8m points)

.net - Is STA Message Loop Required in This Case?

I've got some COM objects I'm creating and running on threads in a .NET application. The threads are marked as Single Threaded Apartments, and everything seems to be working. My understanding is that if these threads try to access COM objects from the main thread then those objects will automatically be marshaled and serialized for me in .NET, so even in that case things will be handled for me, all safe and neat, though maybe a bit slowly.

My question is, while things appear to be working fine, I am not pumping a message loop in the STA threads I'm creating. I'd rather avoid the message loop if I can because of the extra complications it would cause (and possible efficiency losses as well).

I've read a bunch of advice on why the message loop is necessary (mostly from the very helpful Hans Passant), and my understanding is that the message loop gives a place on a thread A where some other thread B can request that COM objects living on thread A can be marshaled and played with. If that's correct, then as long as no other threads request anything from the COM objects on thread A, is Thread A safe in not pumping a message loop? Or are there other cases where the message loop might come into play as well?

Am I playing with fire here? And is there ever a case where you ask if you're playing with fire and you're not?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The STA contract requires pumping a message loop. But yes, it is possible to get away with not pumping. There are two major things that can go wrong:

  • Any call that's made on an interface method from another apartment, including another STA thread or a thread in the MTA will not complete. This looks like deadlock in your program, the call simply never returns. Beware that you can control your own calls quite well but you don't know what the COM component is doing. It may well start a thread itself. You can see this in the debugger with Debug + Windows + Threads. Make sure you are running the debugger in unmanaged mode and that you can account for all the threads you see. Not particularly easy btw.

  • Many apartment threaded COM components count on having a message loop taking care of their own needs. It could be something innocuous as a Timer, it won't tick when there's no loop. Or it may do marshaling internally. Use Spy++ and check if there are any hidden windows owned by your new STA thread, sure sign of trouble if you see one. The diagnosis is the component just misbehaving. Not raising events is a common mishap.

Nothing really to nail to a wall when you don't know enough about the internals of the server. Be sure to test the heck out of it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...