0

MVVM パターンを使用して WPF アプリケーションを開発しています。

アプリはサーバーからキャプチャ イメージを読み込み、準備ができたら WPF フォームのイメージに割り当てます。次のように、BackgroundWorker を使用してスレッドを実行しています。

Window がロードされると、以下が呼び出されます。

BackgroundWorker _bgWorker = new BackgroundWorker();

_bgWorker.DoWork += GetCaptchaImage;
_bgWorker.RunWorkerAsync();

GetCaptchaImage 関数はかなり単純で、画像を別のスレッドにロードします。

BitmapSource _tempBitmap = GetCaptchaFromServer();

Dispatcher を呼び出して、この ImageSource を Window のイメージ ソースに割り当てる方法を知る必要があります。現在、次のように _tempBitmap を読み込んだ後に Dispatcher を呼び出します。

Application.Current.Dispatcher.Invoke(
new Action(() => CaptchaBitmap = _tempBitmap));

CaptchaBitmap が画像ソースにデータバインドされている場所。

ただし、これを行うと、InvalidOperationException がスローされ、_tempBitmap への参照は GUI スレッドでエラーを返します。BackgroundWorker スレッドで作成されたときにディスパッチャー GUI スレッドからアクセスしているため、それはわかっていますが、どうすれば回避できますか?

助けていただければ幸いです。:)

4

4 に答える 4

5

Dispatcher.Invoke を呼び出す前に BitmapSource.Freeze を呼び出すだけです。

BitmapSource _tempBitmap = GetCaptchaFromServer();
_tempBitmap.Freeze();
Application.Current.Dispatcher.Invoke(
new Action(() => CaptchaBitmap = _tempBitmap));

すべての WPF オブジェクトは、それらを作成したスレッドからのみアクセスできます。例外は、Dispatcher (明らかな理由から) と、Freeze メソッドを呼び出した後の Freezable です。

Freeze を呼び出した後、オブジェクトは任意のスレッドからアクセスできます (ただし、変更することはできません)。幸運なことに、BitmapSource は Freezable から継承されます。

于 2009-08-04T10:46:13.230 に答える
0

@Arcturus、私の経験からすると、サーバーからのダウンロードが完了するまでUIの応答性が得られません...実際にUIスレッドを中断してからダウンロードしているため...私は作ってきました私のプロジェクトのいくつかでこの間違いがあり、なぜUIが応答しないのか疑問に思っています....

于 2009-08-05T11:52:03.457 に答える
0

私は同じ問題を抱えていましたWPF: UIスレッドとバックグラウンドスレッドの間でオブジェクトを渡す 「正しい」ソリューションが何であるかを理解していません。私の BackgroundWorker を DispatcherTimer に置き換えて、一度だけ実行され、それが機能しました。

于 2009-08-04T09:41:57.120 に答える
0

好奇心から.. BackgroundWorker クラスの代わりに Dispatcher スレッドですべての画像の取得と設定を行ってみませんか?

Dispatcher.Invoke(DispatcherPriority.Background,
    new Action(() => { CaptchaBitmap = GetCaptchaFromServer(); } )
);
于 2009-08-04T09:51:56.053 に答える