Managed and Unmanaged Threading
COM components use apartments to synchronize access to resources. In contrast, managed objects use synchronized regions, synchronization primitives such as mutexes, locks and completion ports, and synchronized contexts to ensure that all shared resources are used in a thread-safe manner. For additional information about the .NET threading model, see Managed Threading.
For interoperability, the common language runtime creates and initializes an apartment when calling a COM object. A managed thread can create and enter a single-threaded apartment (STA) that contains only one thread, or a multi-threaded apartment (MTA) that contains one or more threads. When a COM apartment and a thread-generated apartment are compatible, COM allows the calling thread to make calls directly to the COM object. If the apartments are incompatible, COM creates a compatible apartment and marshals all calls through a proxy in the new apartment.
The runtime calls CoInitializeEx to initialize the COM apartment as either an MTA or an STA apartment. In the .NET Framework version 2.0, managed threads are initialized as MTA if their apartment state has not been set prior to starting the thread. Use the SetApartmentState or TrySetApartmentState method to set the apartment state before starting the thread.
In the .NET Framework version 2.0, the main application thread is initialized as MTA unless the STAThreadAttribute is applied to the entry point procedure.
Note |
---|
In the .NET Framework versions 1.0 and 1.1, it was possible to set the apartment state after the thread was running by using the System.Threading.ApartmentState property; this created a race condition. In the .NET Framework version 2.0, this is not permitted. |
Some programming models require that you set the STA property on a thread. For example, for Windows Forms to initialize elements such as drag and drop, you must create and enter a single-threaded apartment.
Note |
---|
If neither the proxy and stub nor the type library is registered, an InvalidCastException can occur when calling a COM object from managed code. |
The following table lists the ApartmentState enumeration values and shows the comparable COM apartment initialization call.
ApartmentState enumeration value | COM apartment initialization |
---|---|
MTA |
CoInitializeEx(NULL, COINIT_MULTITHREADED) |
STA |
CoIntializeEx(NULL, COINIT_APARTMENTTHREADED) |
Unknown |
CoInitializeEx(NULL, COINIT_MULTITHREADED) |
Whenever the COM object and the managed thread are in incompatible apartments, all calls on the object are made through a COM-created proxy.
See Also
Concepts
Exposing COM Components to the .NET Framework
Exposing .NET Framework Components to COM