title: How to handle COM events from a console application?
body: <p>I'm using a COM object from a third party library that generates periodic events. When I use the library from a Winforms app, having the object as a class member and creating it in the main form thread, everything works. However, if I create the object from another thread, I don't receive any event.</p>
  
  <p>My guess is that I need to have some kind of event loop in the same thread used to create the object. </p>
  
  <p>I need to use this object from a console application. I guess I could use Application.DoEvents, but I'd rather not include the Winforms namespace in a console App.</p>
  
  <p>How can I solve this problem?</p>
  
  <p><strong>Update 3 (2011-06-15):</strong> The vendor has answered at last. In short, they say there is some difference between the message pump created by Application.Run and the one created by Thread.Join, but they don't know what that difference is. </p>
  
  <p>I agree with them; any light shed on this matter would be very appreciated.</p>
  
  <p><strong>Update:</strong> </p>
  
  <p>From Richard comment to mdm answer:</p>
  
  <p><em>if there other component is single threaded and instantiated from an MTA then Windows will create the worker thread + window + message pump and do the necessary marshalling.</em></p>
  
  <p>Trying to follow his advice, I'm doing the following:</p>
  
  <p><strong>Update 2:</strong> </p>
  
  <p>I'm changed the code following João Angelo answer.</p>
  
  <pre><code>using System;
  
  namespace ConsoleApplication2
  {
      class Program
      {
          [STAThread]
          static void Main(string[] args)
          {
              MyComObjectWrapper wrapper = new MyComObjectWrapper();
          }
      }
  
      class MyComObjectWrapper
      {
          MyComObject m_Object;
          AutoResetEvent m_Event;
  
          public MyComObjectWrapper()
          {
              m_Event = new System.Threading.AutoResetEvent(false);
  
              System.Threading.Thread t = new System.Threading.Thread(() =&gt; CreateObject());
              t.SetApartmentState (System.Threading.ApartmentState.STA);
              t.Start();
  
              Wait();
          }
  
          void ObjectEvt(/*...*/)
          {
              // ...
          }
  
          void Wait()
          {
              m_Event.WaitOne();
          }
  
          void CreateObject()
          {
              m_Object = new MyComObject();
              m_Object.OnEvent += ObjectEvt;
  
              System.Threading.Thread.CurrentThread.Join();
          }    
      }
  }
  </code></pre>
  
  <p>I have also tried the following instead:</p>
  
  <pre><code>        public MyComObjectWrapper()
          {
              CreateObject();
          }
  </code></pre>