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();
4

2 回答 2

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;
    }


}
于 2012-12-19T21:40:45.780 回答
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();
于 2012-10-18T07:54:52.537 回答