【问题标题】:Multiwindow behaviour and dispatcher in WPFWPF 中的多窗口行为和调度程序
【发布时间】:2018-10-07 08:44:04
【问题描述】:

我有 2 个窗口的应用程序。 第一个登录窗口用于验证用户并启动主应用程序。我为此使用线程并运行调度程序:

                    private bool EndTrigger = false;

                    /.../

                    Thread thread = new Thread(() =>
                    {
                        MainWindow T_window = new MainWindow(t_data);
                        T_window.WindowState = WindowState.Maximized;
                        T_window.Show();
                        EndTrigger = true;

                        System.Windows.Threading.Dispatcher.Run();

                    });

                    thread.SetApartmentState(ApartmentState.STA);
                    thread.Start();

在 LoginWindow 关闭之后。我使用了检查 MainWindow 是否准备好的函数和这样的 Timer:

Timer LoginWinClose = new Timer(new TimerCallback(IfLoginWinCanBeClosed), null, 2000, 1000);

    public void IfLoginWinCanBeClosed(Object stateInfo)
    {
        if (EndTrigger)
        {
            this.Dispatcher.Invoke(new Action(delegate
              {                      
                  this.Close();
              }));
        }
    }

一切正常:LoginWindow 消失,MainWidow 出现,一切正常。

但是当我尝试在 MainWindow 中再创建一个窗口时,我得到一个异常提示:应用程序正在关闭。

看起来关闭 LoginWindow 会导致尝试关闭应用程序,但是如果我关闭任何其他窗口(例如 MainWindow),我仍然可以从 LoginWondow 再创建一个而不会出现任何错误。 目前我通过改变来解决这个问题

this.Close();

this.Visibility = Visibility.Collapsed;

表示 LoginWindow 会一直持续运行。是否有其他解决方案?

【问题讨论】:

  • 你为什么到处使用Dispatcher?这段代码写在哪里?
  • 我只在某一时刻使用它——在检查 MainWindow 是否已加载时,因为这是后台线程。

标签: wpf multithreading dispatcher


【解决方案1】:

感谢@Sham,我明白错误在哪里! 代码,在单独的线程中创建新窗口(这是因为登录检查操作在单独的线程中运行以避免挂起 LoginWindow),所以我在该线程中创建并运行具有单独调度程序的新窗口,而不是主 UI 线程。 因此,解决方案非常简单。只需稍作修改即可:

                    Thread thread = new Thread(() =>
                    {  
                        this.Dispatcher.Invoke(new Action(delegate
                        {
                            AdminWindow T_window = new AdminWindow(t_data);
                            T_window.WindowState = WindowState.Maximized;
                            T_window.Show();
                            t_data.Link_auth_win.EndTrigger = true;
                            System.Windows.Threading.Dispatcher.Run();
                        }));
                    });

                    thread.SetApartmentState(ApartmentState.STA);
                    thread.Start();

【讨论】:

    猜你喜欢
    • 2018-02-25
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多