来自另一个线程的消息框

时间:2012-10-18 07:29:10

标签: c# multithreading

编辑: 我得到的错误与我的问题无关。 :/ -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();

2 个答案:

答案 0 :(得分:3)

(这个答案适用于WPF。)

好吧,你可以打开一个消息框 - 让我们说 - 一个工作线程,但你不能将它的父设置为属于UI线程的东西(因为工作线程会通过添加一个新的子节点来改变父窗口,父窗口不属于工作线程,它通常属于UI线程),所以你基本上被迫离开父null。

如果用户不关闭它们但重新激活应用程序窗口,这将导致一堆消息框位于应用程序窗口后面。

您应该做的是使用正确的父窗口在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;
    }


}

答案 1 :(得分:2)

只需在该线程上显示正常的消息框即可。 “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();