Как сделать делегат нить STA - PullRequest
3 голосов
/ 23 марта 2011

Я видел некоторое обсуждение этой темы и пришел к выводу, что это невозможно.Я должен использовать 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 Ответ

4 голосов
/ 23 марта 2011

Это невозможно.Метод BeginInvoke () делегата всегда использует поток пула потоков.И потоки TP всегда являются MTA, которые нельзя изменить.Чтобы получить поток STA, вы должны создать поток и вызвать его метод SetApartmentState () перед его запуском.Этот поток также должен прокачать цикл сообщений Application.Run ().COM-объект использует его только тогда, когда его экземпляр был создан в этом потоке.

Не уверен, что вы пытаетесь сделать, но попытка многопоточности фрагмента кода, который не является потокобезопасным просто не можетРабота.COM обеспечивает это.

...