2009-04-24 54 views
6

如何強制一段代碼在我的主線程上執行?在主線程上強制執行代碼

這就是爲什麼我想知道:

我有時常會從一個線程是不是主線程顯示自定義創建的消息框。但是,當消息框構造函數被調用時,我得到一個InvalidOperationException異常,說「調用線程必須是STA,因爲許多UI組件需要這個。」這是有道理的,UI元素需要在主線程上處理。

My MessageBox.ShowMessage(...)函數是一個靜態函數,它創建自定義消息框的實例並顯示它。有什麼我可以放在ShowMessage中強制消息框被創建並顯示在主線程上?在我的代碼中的其他地方,我使用Control.BeginInvoke來處理類似的問題,但由於它是一個靜態函數,因此我沒有現有的UI元素來調用BeginInvoke。

是否必須使用Control.BeginInvoke調用MessageBox.ShowMessage?我更喜歡在ShowMessage中調用BeginInvoke(或一些等價的)。

回答

5

有幾個選擇這裏:

  • 使第二個線程STA(你只能爲自己的Thread做到這一點 - 爲ThreadPool線程不) - 通過.SetApartmentState(ApartmentState.STA);
  • 看看SynchronizationContext.Current是非空值;如果是這樣,使用Send/Post
  • 在通過窗體/控件作爲ISynchronizeInvoke實例(可能並不適用於WPF - 我不是100%確定)
+0

您是否有鏈接解釋如何執行您列出的第一個選項? – w4g3n3r 2009-04-24 21:41:02

+0

在啓動線程之前調用Thread.SetApartmentState()。 – itowlson 2009-04-24 21:44:08

+0

創建線程時,只需調用。(編輯)答案中顯示的.SetApartmentState。首先讓我知道是否需要更多幫助來創建線程。 – 2009-04-24 21:44:25

5

你的想法是正確的 - 爲了讓它正常工作,你將需要從主線程調用它。

最簡單的方法?當您啓動主窗體時,將引用保存在ShowMessage()調用可見的靜態變量中。然後,你可以ShowMessage做標準:

if(myForm.InvokeRequired) 
{ 
    myForm.Invoke(() => ShowMessage(arg1,arg2,arg3)); 
    return; 
} 
.... other code here.... 
1

,而不是直接顯示在消息框中,只是將消息發送到你的主線程,這標誌着主線程顯示一個消息框。

相關問題