.NET ServicedComponents and STA Apartment

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(

  delegate(object a)

  {

    ComInstance o = new ComInstance();

    Thread tt = new Thread(

       delegate(object q)

       {

         // A deadlock will be detected here
o.ComMethodCall();

       });

    tt.Start();

    while (true)

    {

      // keep the thread alive

      // must pump the message loop

      // ...

    }

  });

t.SetApartmentState(ApartmentState.STA);

t.Start();
Console.ReadLine();