0

在 prism 应用程序中,我创建了一个以模块开头的登录表单。用户通过身份验证后,登录表单等待所有应用程序模块已初始化(如 splah 屏幕显示有关已加载模块的一些信息),然后启动 shell。一切似乎都工作正常,除非用户单击登录表单的取消按钮。我希望应用程序关闭,但由于登录表单在另一个线程中启动,我无法使用 Application.Current.Shutdown() (仅适用于 Enviroment.Exit(0) 但我不确定这是一个正确的方法)。我尝试从 Application.Current.Dispatcher 调用,但应用程序仍在运行。这是登录模块初始化,我在其中捕获应该关闭应用程序的事件:

public void Initialize()
{        
  Dispatcher.CurrentDispatcher.BeginInvoke(
    (Action) (() =>
        {
            Shell.Show();

            EventAggregator.GetEvent<LoginStatusEvent>().Publish(new LoginStatusEvent { LoginStatus = LoginViewStatus.Close });
        }));      

  ThreadStart showSplash =
    () =>
      {
        Dispatcher.CurrentDispatcher.BeginInvoke(
          (Action) (() =>
                {
                    Container.RegisterType<LoginViewModel, LoginViewModel>();
                    Container.RegisterType<LoginView, LoginView>();

                    var login = Container.Resolve<LoginView>();

                    EventAggregator.GetEvent<LoginStatusEvent>().Subscribe(e => login.Dispatcher.BeginInvoke(
                        (Action)(() =>
                            {
                                if (e.LoginStatus == LoginViewStatus.Aborted)
                                {
                                    login.Close();

                                    Application.Current.Dispatcher.BeginInvoke((Action)(() => Application.Current.Shutdown()));

                                    //Environment.Exit(0);
                                }
                                else if (e.LoginStatus == LoginViewStatus.Close)
                                {
                                    login.Close();                                          
                                }
                                else
                                {
                                    WaitForCreation.Set();
                                }
                            })));

                    login.Show();                            
                }));

        Dispatcher.Run();
      };

  WaitForCreation = new AutoResetEvent(false);

  var thread = new Thread(showSplash) {Name = "LoginView Thread", IsBackground = true};
  thread.SetApartmentState(ApartmentState.STA);
  thread.Start();

  WaitForCreation.WaitOne();
}

任何帮助表示赞赏!

4

1 回答 1

0

为什么您的登录 UI 在后台线程上运行?似乎登录 UI 应该在 GUI 线程上运行。然后你有一个 BackgroundWorker 对象(比上面的代码更容易使用并且更易于维护),当 ProgressChanged 方法回调到 GUI 线程时,它可以在需要更新 UI 时随时运行 ProgressChanged?

我经常将 BackgroundWorker 重载为类似于 MyDataObjectBackgroundWorker 的东西,并且我创建了一个属性来保存我的对象。通过这种方式,我可以使用 ProgressChanged 轻松地来回传递数据(比如正在加载的模块的信息)。

于 2012-11-11T16:35:24.290 回答