6

バックグラウンド:

MEF フレームワークを使用してアプリに必要なライブラリとコンポーネントを自動的にリンクする WPF アプリケーションに取り組んでいます。独自のコンポーネントを追加すると、低速のマシンでは読み込みに 0 ~ 2 秒から 6 ~ 7 秒かかります。そのためには、アプリケーションがロード中であることをユーザーに知らせる素敵なスプラッシュ スクリーンが必要になると思います。理想的には、スプラッシュ スクリーンには、アニメーション化されたプログレス バーと、どのコンポーネントがロードされているかを説明するステータス テキスト フィールドが表示されます。

問題:

OnStartupアプリケーションの開始直後 ( ) に呼び出され、続いて MEF ブートストラップが読み込まれるスプラッシュ スクリーン ウィンドウを設計しました。問題はもちろん、ウィンドウが MEF ブートストラッパーの読み込みと同じスレッド上にあるため、ウィンドウがアニメーション化されないことです。ブートストラッパーを別のスレッドに配置しようとしましたが、STA スレッドではないと不平を言っています。STA スレッドでさえ、それでも気に入らず、メイン アプリ ウィンドウをロードしようとするとエラーがスローされました。スプラッシュ スクリーン ウィンドウ自体を別のスレッドに配置することはできません。これは、アクセスできないためです。また、UI コンポーネントであるため、STA スレッドにする必要があります。(これは真実ではないことに気づきました。スレッドと話すことができます)

アップデート

スプラッシュ スクリーン ウィンドウを別の STA スレッドに保持する解決策を見つけました。私を正しい方向に向けてくれたことに答えてくれたみんなに感謝します:

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        Dispatcher threadDispacher = null;
        Thread thread = new Thread((ThreadStart)delegate
        {
            threadDispacher = Dispatcher.CurrentDispatcher;
            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(threadDispacher));

            loadingWindow = new LoadingWindow();
            loadingWindow.Closed += (s, ev) => threadDispacher.BeginInvokeShutdown(DispatcherPriority.Background);
            loadingWindow.Show();

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

        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();

        var bootstrapper = new Bootstrapper();
        bootstrapper.Run();

        if (threadDispacher != null)
        {
            threadDispacher.BeginInvoke(new Action(delegate { loadingWindow.Close(); }));
        }
    }
4

1 に答える 1

0

ブートストラップを独自のスレッドに移動するのは正しい方法でした。ただし、UI スレッドで実行する必要がある部分も UI スレッドで呼び出されるようにする必要があります。

そのため、MEF ブートストラップが完了すると、MEF のスレッドからでも、メイン スレッドでスプラッシュ ウィンドウの非表示とメイン ウィンドウの表示を呼び出すことができます。

メッセージをメイン スレッドに渡す方法は、ディスパッチャを使用することです

于 2013-07-25T14:45:01.430 に答える