2011-03-23 55 views
3

我看到圍繞這一話題進行一些討論,認爲這是不可能的。我應該使用線程,使它成爲STA,當我需要返回結果時,將主線程與創建的線程連接起來。這可以工作,但它不是一個理想的解決方案,因爲使用委託我可以實現純異步行爲(使用回調)。所以,在我開始實現我自己的Future類之前(如在Java中);有沒有更好的方式來實現這個使用代表?如何使代表線程STA


    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 
    } 

回答

4

這是不可能的。委託的BeginInvoke()方法始終使用線程池線程。 TP線程始終是MTA,不能更改。爲了得到一個STA線程,你必須創建一個線程並啓動它之前調用它SetApartmentState()方法。這個線程還必須抽取一個消息循環,Application.Run()。 COM對象只在其實例在該線程中創建時才使用它。

不知道你正在嘗試做的,但如果想要多線程的代碼不是線程安全的就不能正常工作一大塊。 COM強制執行該操作。

+0

其實,我想從我的WinForm應用程序訪問華廷的API。幾乎所有由Watin公開的API都需要在STA中進行。我想在與主UI線程不同的線程中打開一個IE窗口。 – karephul 2011-03-23 18:16:09

+0

檢查這個答案:http://stackoverflow.com/questions/4269800/c-webbrowser-control-in-a-new-thread/4271581#4271581 – 2011-03-23 18:19:19

+0

哦,謝謝!漢斯這幾乎是我一直在尋找.. :)所以我使用線程,將它設置爲STA和定義事件,使其純異步(回調).. C#岩石 – karephul 2011-03-23 20:49:42