2011-09-21 76 views
0

嗨,獲取mainThread再次運行?

我有一個託管WCF服務(了NamedPipes)一個WinForm應用程序。在接電話時,一個事件將被觸發,然後一個表格將被創建並打開。問題是,我得到的跟隨着例外

ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment. 

當的WinForms InitializeComponent方法創建一個System.Windows.Forms.WebBrowser?

我認爲另一個線程正在運行even(工作線程),我怎樣才能讓主線程運行事件?

我沒有任何打開的winform,所以我不能使用InvokeRequired。

BestRegards

EDIT1:普萊斯不,我使用

[STAThread] 
public static void Main(string[] args) 
{ 
Application.Run(_instance); 
} 

回答

0

我的解決方案是在啓動時創建一個虛擬winform,當我需要主UI線程時,我將在此虛擬表單上使用invoke。

它會使用更多的資源,但我沒有看到一個更簡單的方法。

0

這WCF調用最有可能即將在比主UI線程的線程上。所有UI控件(包括ActiveX控件)必須通過UI線程創建和訪問,並且只能通過UI線程訪問。你得到的錯誤是指出創建線程甚至不在單線程公寓(STA)中,這也是一個要求。

要獲得在主UI線程上執行的代碼,請使用Control.Invoke方法。它會將代理的執行管理到託管目標ControlForm的線程上。

如果您沒有提及立即可用的ControlForm,那麼您將需要創建一個。您可能必須創建一個運行消息循環的線程。這可以通過Application.Run完成。創建隱藏的Form足夠簡單,可以用來呼叫Invoke

下面是它的樣子。

void SomeMethodExecutingOnThreadPool() 
{ 
    var form = null; 
    var mre = new ManualResetEvent(false); 

    // Create the UI thread. 
    new Thread(
    () => 
    { 
     form = new Form(); 
     form.Load += 
     (sender, args) => 
     { 
      mre.Set(); 
     } 
     Application.Run(form); 
    }).Start(); 

    // Wait for the UI thread to initialize. 
    mre.WaitOne(); 

    // You can now call Invoke. 
    form.Invoke(/* ... */); 
} 
+0

但是,如果我在當前線程池線程上創建窗體或控件,winform是否不會綁定到此線程?我聽說創建窗體/控件的線程必須是更新窗體/控件的線程?或者當創建新的表單/控件並執行工作時,主UI線程會進入嗎?你能否提供一個小例子? – Banshee

+0

@SnowJim:我更新了我的答案。你將不得不手動創建一個UI線程。 –

+0

謝謝,但如果應用程序在主UI線程上運行其他部分(使用Application.Run),這將會很奇怪。我可不能簡單地將當前的UI線程在啓動時存儲在屬性中,然後使用此線程觸發事件? – Banshee

1

這些類型的調用是在線程池線程上進行的。它們不適合顯示任何UI。你需要創建的對味自己的線程:

 var t = new Thread(() => { 
      Application.Run(new Form1()); 
     }); 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 

有你這個被爭奪等實際問題,你不能只是彈出一個窗口,而不參與用戶。典型的意外事故是用戶意外關閉它,甚至沒有看到它,或者窗戶在用戶正在使用的窗戶後面消失。如果你已經有一個用戶界面,那麼一定要使用Control.BeginInvoke()讓主線程顯示窗口。考慮用NotifyIcon輕觸,在托盤通知區域顯示氣球以提醒用戶。

+0

謝謝,但主UI線程在哪裏?我應該不使用該線程嗎? – Banshee

+0

@SnowJim:和我一樣,我懷疑漢斯還假定沒有UI線程存在。 –

+0

抱歉不清楚。應用程序將以[STAThread] public static void Main(string [] args)開頭,然後是Application.Run(_instance);.我認爲這將意味着一個UI線程將被創建(messagepump)。到目前爲止,我的解決方案是在啓動時以及需要UI線程時創建一個dummyForm(從未顯示)。Invoke將用於此虛擬表單。壞/神? – Banshee

相關問題