0

私は App.Xaml にこれを持っています:

public App()
{
    _backgroundWorker = new BackgroundWorker();
    _backgroundWorker.DoWork += new DoWorkEventHandler(DoBackgroundWork);
    _backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundCompleted);
    _backgroundWorker.RunWorkerAsync();

    _splashView = new SplashView();
    _splashView.Show();
}

このDoBackgroundWorkメソッドはデータベースのセットアップを実行し、BackgroundCompletedイベントは を閉じて_splashViewを表示します_mainView

ただし、_splashViewfrom内の何かを変更するBackgroundCompletedと、クロス スレッド例外が発生します。これは、バックグラウンド ワーカーが修正するように設計されていると考えていたものです。これは、backgroundworker の作業方法と関係があると思いますApp.Xaml。たぶん、これはスプラッシュスクリーンを行うには悪い方法ですか?

4

3 に答える 3

0

バックグラウンド ワーカーは SynchronizationContext を使用します。これはメモリからのものですが、App コンストラクターで初期化されているとは思いません。

BW を構築する前に、SynchronizationContext.Current が null でないことを確認してください。また、SynchronizationContext.Current が BW の構築前と完了したメソッドで同じであることを確認します。

そうでない場合は、プロセスの後半でコードを移動する必要があります... App.OnStartUp は問題ないはずです

于 2013-01-07T19:31:57.670 に答える
0

たぶん、これはスプラッシュスクリーンを行うには悪い方法ですか?

あなたの質問を誤解していない限り、スプラッシュ スクリーンを表示するためにこれを行う必要はないと思います。画像を選択し、[プロパティ] ウィンドウでBuildActionドロップダウンをクリックして を選択しますSplashScreenBackgroundWorkerまた、データ関数に時間がかからない限り、を削除することでプロセスを簡素化できると思います。スプラッシュ画面の表示/非表示に対応するために追加したと思います。

于 2013-01-07T19:43:44.557 に答える
-1

イベント ハンドラがどのスレッドのOnWorkCompleted実行に使用されるかは保証されません。

同様の質問を参照してくださいBackgroundWorker OnWorkCompleted がクロススレッド例外をスローします

バックグラウンド スレッドからビジュアル要素を変更するには、Invokeまたはメソッドを使用する必要があります。BeginInvokeこれは、プロパティを変更するオブジェクトで直接呼び出すか、Dispatcher.

編集:アダムとの会話によると

には、 (BackgroundWorker のスレッドではなく) 初期スレッドで実行されるイベント ハンドラーにSynchronizationContext望ましい効果があります。http://msdn.microsoft.com/en-us/magazine/gg598924.aspx。(図 2 参照)OnWorkCompleted

If the BackgroundWorker is created and run prior to the SynchronizationContext initialization, then the OnWorkCompleted will execute on possibly the same thread as the BackgroundWorker.

Thanks Adam.

于 2013-01-07T19:22:27.383 に答える