2012-10-18 81 views
0

編輯: 我得到的錯誤與我的問題無關。 :/ -1來自另一個線程的消息框

我在一個新線程上啓動一個服務,然後我想捕獲一個錯誤並顯示一個消息框。因爲它不在UI線程中,我得到一個錯誤。我怎樣才能解決這個問題?

(WPF窗口)

代碼:

xmlServiceHost = XcelsiusServiceHost.CreateXmlServiceHost(Properties.Settings.Default.XmlDataService); 

serviceThread = new Thread(_ => 
{ 
    try { xmlServiceHost.Open(); } 
    catch (AddressAccessDeniedException) 
    { 
    CreateRegisterDashboardServiceFile(); 

    //Error not in UI thread. 
    //this.ShowUserInfoMessage("The dashboard service needs to be registered. Please contact support."); 
    } 
}); 

serviceThread.Start(); 
+0

WPF或WinForms?還值得添加錯誤的確切文本,以便在使用錯誤消息進行搜索時,具有相同問題的其他人會發現您的問題。 – dash

+0

如果它是Windows窗體應用程序,則可以簡單地避免將父窗口句柄傳遞給MessageBox,並且它可以工作。 –

+1

顯示方法'ShowUserInfoMessage'的主體也會有所幫助 – dash

回答

1

僅僅只是在該線程正常的消息框,工作正常。 「this」關鍵字並在我的UI線程上調用方法是個問題。

xmlServiceHost = XcelsiusServiceHost.CreateXmlServiceHost("http://localhost:123/naanaa");//Properties.Settings.Default.XmlDataService); 

serviceThread = new Thread(_ => 
{ 
    try { xmlServiceHost.Open(); } 
    catch (AddressAccessDeniedException) 
    { 
    CreateRegisterDashboardServiceFile(); 
    System.Windows.MessageBox.Show("The dashboard service needs to be registered. Please contact support."); 
    } 
}); 

serviceThread.Start(); 
+0

是的; MessageBox.Show應該是'線程安全的' - http://stackoverflow.com/questions/10283881/messagebox-on-worker-thread – dash

+0

你應該添加到你原來的問題,而不是一個答案。 – Tudor

+0

但是,這是答案,如果我將它添加到問題中,那麼就沒有問題或答案只是一個聲明? – hotpie

3

(這個答案是對WPF)

好了,你可以打開一個消息框 - 讓說 - 工作線程,但你不能其父設置的東西,屬於UI線程(因爲工作者線程會通過添加一個新子項來更改父窗口,並且父窗口不屬於工作線程,所以它通常屬於UI線程),所以基本上被迫將父項留空。

如果用戶不關閉它們,但重新激活應用程序窗口,這將導致一堆消息框位於應用程序窗口後面。

你應該做的是用適當的父窗口在UI線程上創建消息框。爲此,您需要用於UI線程的調度程序。調度員將在UI線程上打開消息框,並可以設置其正確的父項。

在這樣的情況下,我通常通過UI調度到工作線程,當我啓動線程,然後用一個小的輔助類,這是爲工作線程處理異常時特別有用。

/// <summary> 
/// a messagebox that can be opened from any thread and can still be a child of the 
/// main window or the dialog (or whatever) 
/// </summary> 
public class ThreadIndependentMB 
{ 
    private readonly Dispatcher uiDisp; 
    private readonly Window ownerWindow; 

    public ThreadIndependentMB(Dispatcher UIDispatcher, Window owner) 
    { 
     uiDisp = UIDispatcher; 
     ownerWindow = owner; 
    } 

    public MessageBoxResult Show(string msg, string caption="", 
     MessageBoxButton buttons=MessageBoxButton.OK, 
     MessageBoxImage image=MessageBoxImage.Information) 
    { 
     MessageBoxResult resmb = new MessageBoxResult(); 
     if (ownerWindow != null) 
     uiDisp.Invoke(new Action(() => 
     { 
      resmb = MessageBox.Show(ownerWindow, msg, caption, buttons, image); 

     })); 
     else 
      uiDisp.Invoke(new Action(() => 
      { 
       resmb = MessageBox.Show(msg, caption, buttons, image); 

      })); 
     return resmb; 
    } 


} 
相關問題