A major issue with running all COM components using STA threads is that the thread which calls CoInitializeEx must be the only thread executing method invocations on that COM instance. Now assume a scenario in which the STA thread is busy performing other activities. In those scenarios you will receive an exception similar to the following and the way around that is to somehow ensure that the message loop on the STA thread is being pumped frequently. In other words anything causing a delay in this process may be an issue and you may receive an exception similar to the following:
“ContextSwitchDeadlock was detected
The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.”
Here is an example of the problem (ComInstance is a ServicedComponent):
Thread t = new Thread(
ComInstance o = new ComInstance();
Thread tt = new Thread(
// A deadlock will be detected here o.ComMethodCall();
// keep the thread alive
// must pump the message loop
PingBack from http://msdnrss.thecoderblogs.com/2007/08/05/net-servicedcomponents-and-sta-apartment/
I have a question regarding STA/MTA in .net
I need to build a COM object in .net whose threading model is required to be STA only (not Both,..).
is it possible?
thanks in advance
Ok.. it doesn't really make sense to create a STA ServicedComponent.
If you want STA behaviour, then you could create a thread in .NET in STA apartment and use that thread to call into your component. This way, because the COM instance was created using a STA thread, it will remain in single threaded apartment.
See here for more info.
The problem is that my component is called via remoting (so MTA threads) & it makes calls to a 3rd party COM component which , for some unknown reason, doesn't work with MTA threads.
So I wanted to shield the calls to the 3rd party COM component using my own STA COM component. This way calls come through MTA remoting threads will be converted to STA ( message queue,..) calls by COM itself & I don't have to implemet my own message queue
if I use Backgroundworker control and in Dowork event I use COM, how I can set STA Apartment ??
Regularly I don’t make comments on blogs, but I’ve to point out that it article really forced me to try and do so. Really fabulous blog post.