invalidApartmentStateChange MDA

The invalidApartmentStateChange managed debugging assistant (MDS) is activated by either of two problems:

  • An attempt is made to change the COM apartment state of a thread that has already been initialized by COM to a different apartment state.

  • The COM apartment state of a thread changes unexpectedly.

Symptoms

  • A thread's COM apartment state is not what was requested. This may cause proxies to be used for COM components that have a threading model different from the current one. This in turn may cause an InvalidCastException to be thrown when calling the COM object through interfaces that are not set up for cross-apartment marshalling.

  • The COM apartment state of the thread is different than expected. This can cause a COMException with an HRESULT of RPC_E_WRONG_THREAD as well as a InvalidCastException when making calls on a Runtime Callable Wrapper (RCW). This can also cause some single-threaded COM components to be accessed by multiple threads at the same time, which can lead to corruption or data loss.

Cause

  • The thread was previously initialized to a different COM apartment state. Note that the apartment state of a thread can be set either explicitly or implicitly. The explicit operations include the Thread.ApartmentState property and the SetApartmentState and TrySetApartmentState methods. A thread created using the Start method is implicitly set to MTA unless SetApartmentState is called before the thread is started. The main thread of the application is also implicitly initialized to MTA unless the STAThreadAttribute attribute is specified on the main method.

  • The CoUninitialize method (or the CoInitializeEx method) with a different concurrency model is called on the thread.

Resolution

Set the apartment state of the thread before it begins executing, or apply either the STAThreadAttribute attribute or the MTAThreadAttribute attribute to the main method of the application.

For the second cause, ideally, the code that calls the CoUninitialize method should be modified to delay the call until the thread is about to terminate and there are no RCWs and their underlying COM components still in use by the thread. However, if it is not possible to modify the code that calls the CoUninitialize method, then no RCWs should be used from threads that are uninitialized in this way.

Effect on the Runtime

This MDA has no effect on the CLR.

Output

The COM apartment state of the current thread, and the state that the code was attempting to apply.

Configuration

<mdaConfig>  
  <assistants>  
    <invalidApartmentStateChange />  
  </assistants>  
</mdaConfig>  

Example

The following code example demonstrates a situation that can activate this MDA.

using System.Threading;  
namespace ApartmentStateMDA  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);  
        }  
    }  
}  

See also