如何制作委托线程STA

时间:2011-03-23 16:03:25

标签: c# delegates threadpool

我看到围绕这个主题的一些讨论,并得出结论认为这是不可能的。我应该使用Threads,使它成为STA,当我需要返回结果时,将主线程与创建的线程连接起来。这可以工作,但它不是一个理想的解决方案,因为使用委托我可以实现纯异步行为(使用回调)。所以,在我开始实现自己的Future类之前(就像在Java中一样);有没有更好的方法来使用代表实现这一目标?


   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
   }

1 个答案:

答案 0 :(得分:4)

这是不可能的。委托的BeginInvoke()方法始终使用线程池线程。 TP线程始终是MTA,无法更改。要获取STA线程,必须先创建一个Thread并在启动它之前调用其SetApartmentState()方法。该线程还必须泵送一个消息循环Application.Run()。 COM对象仅在该线程中创建其实例时才使用它。

不确定您要做什么,但尝试多线程一些非线程安全的代码无法正常工作。 COM强制执行。