2012-10-18 82 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; 
    } 


} 
相关问题