This article has been archived. It is offered "as is" and will no longer be updated.
When you make a blocking call from your Component Object Model (COM) object instance that is living in a single-threaded apartment (STA), all other COM instances that live in that STA are waiting for your instance to unblock the apartment. If you need to make a blocking call from a component, it is recommended that you make the blocking call from a component whose threading model is Free.
A call is considered blocking if it takes a long or indeterminate amount of time to return, for example calls to the backend, network calls that use remote procedure call (RPC), or sockets.
In addition, Microsoft Visual Basic can only create STA applications and components whose threading model is Apartment or missing. Thus, you should not make blocking calls from a component that is written in Visual Basic.
Components whose threading model is Apartment live in a single-threaded apartment (STA). Multiple COM object instances can live in the same STA. However, there is only one thread (hence the name) that services all the COM object instances in that apartment. If you make a blocking call from one of those COM object instances, the other COM object instances are starved because the only thread that can service them is blocked.
You should make blocking calls from a component that has a threading model of Free. This component lives in the multithreaded apartment (MTA). As in the STA, multiple COM object instances can live in an MTA. However, the MTA has multiple threads that service its COM object instances. As a result, when this COM object instance makes a blocking call, other threads can service the other COM object instances. These threads can even service the COM object instance that makes a blocking call. Thus, to make your components that live in the MTA thread-safe, you should protect global data with synchronization objects.
When a COM object instance from an STA calls a method on a COM object instance that lives in the MTA and that makes a blocking call, the STA component will not block. This is because when the STA component makes the call through the COM proxy, the proxy sends off the data to the MTA, and COM pumps messages in the STA so that it can do other work in its apartment. (Work in an STA apartment arrives through windows messages.) A different thread in the MTA picks up the COM call through the stub and makes the method call on the COM object instance, which in turn makes the blocking call, effectively putting the thread in a "wait" state. When the blocking call returns, the COM method finishes its work and returns the data back to the stub, which returns data to the proxy through a windows message. The proxy in the STA thread picks up the data in the windows message and sends it back to the calling component.
Another side effect of long blocking calls in an STA is that RPC communicates with the STA through windows messages. The blocking call hinders that communication along with any other potential windows message that may belong to that thread.
For additional information on COM threading, click the article number below to view the article in the Microsoft Knowledge Base: