3

I have see some discussion around this topic and concluded that it is not possible. I should use Threads, make it STA and when I need result back, join main thread with the created thread. This can work but it is not an ideal solution as using delegates I can achieve pure asynchronous behavior (using callback). So, to square one - just before I start implementing my own Future class (as in Java); Is there a better way to achieve this using delegates?


   private delegate String DelegateFoo(String[] input);
   private String Foo(String[] input){
      // do something with input
      // this code need to be STA
      // below code throws exception .. that operation is invalid
      // Thread.CurrentThread.SetApartmentState(ApartmentState.STA)
      return "result";
   }

   private void callBackFoo(IAsyncResult iar){
      AsyncResult result = (AsyncResult)iar;
      DelegateFoo del = (DelegateFoo)result.AsyncDelegate;
      String result = null;
      try{
          result = del.EndInvoke(iar);
      }catch(Exception e){
          return;        
      }

      DelegateAfterFooCallBack callbackDel = new DelegateAfterFooCallBack (AfterFooCallBack);
      // call code which should execute in the main UI thread.
      if (someUIControl.InvokeRequired)
      {   // execute on the main thread.
         callbackDel.Invoke();
      }
      else 
      {
         AfterFooCallBack();
      }
   }
   private void AfterFooCallBack(){
       // should execute in main UI thread to update state, controls and stuff
   }

karephul
  • 1,473
  • 4
  • 19
  • 36

1 Answers1

5

It is not possible. A delegate's BeginInvoke() method always uses a threadpool thread. And TP threads always are MTA, that cannot be changed. To get an STA thread, you must create a Thread and call its SetApartmentState() method before starting it. This thread must also pump a message loop, Application.Run(). The COM object only uses it when its instance was created in that thread.

Not sure what you are trying to do, but trying to multi-thread a chunk of code that is not thread-safe just can't work. COM enforces that.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Actually, I want to access Watin API's from my Winform application. Almost all the API's exposed by Watin need the tread be in STA. I want to open an IE window in a different thread than my main UI thread. – karephul Mar 23 '11 at 18:16
  • Check this answer: http://stackoverflow.com/questions/4269800/c-webbrowser-control-in-a-new-thread/4271581#4271581 – Hans Passant Mar 23 '11 at 18:19
  • Oh Thanks Hans !! that is almost what I was looking for .. :) So I am using Threads, setting it to STA and defining an EVENT to make it pure Asynchronous (with callback) .. C# rocks – karephul Mar 23 '11 at 20:49