WPF中的多窗口行为和调度程序

时间:2018-10-07 08:44:04

标签: wpf multithreading dispatcher

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

                    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 Disapper,MainWidow出现并且一切正常。

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

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

this.Close();

this.Visibility = Visibility.Collapsed;

这意味着LoginWindow将继续一直运行。如果还有其他解决方案?

1 个答案:

答案 0 :(得分:0)

感谢@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();