0

プリズム アプリケーションでは、モジュールで開始するログイン フォームを作成しました。ユーザーが認証されると、ログイン フォームはすべてのアプリケーション モジュールが初期化されるのを待ち (スプラー画面に読み込まれたモジュールに関する情報が表示されるように)、シェルを起動します。ユーザーがログインフォームのキャンセルボタンをクリックした場合を除いて、すべて正常に動作しているようです。アプリケーションをシャットダウンしたいのですが、ログインフォームが別のスレッドで開始されるため、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 スレッドで実行する必要があるようです。次に、ProgressChanged メソッドが GUI スレッドにコールバックするときに UI を更新する必要があるときはいつでも ProgressChanged を実行できる BackgroundWorker オブジェクト (上記のコードよりもはるかに使いやすく、保守しやすい) がありますか?

私はしばしば BackgroundWorker を MyDataObjectBackgroundWorker のようなものにオーバーロードし、オブジェクトを保持するプロパティを作成します。このようにして、ProgressChanged を使用して簡単にデータをやり取りできます (モジュールのロードに関する情報など)。

于 2012-11-11T16:35:24.290 に答える