2009-08-04 5 views
0

私はMVVMパターンを使用してWPFアプリケーションを開発しています。ディスパッチャでWPFオブジェクトにアクセスする方法は?

アプリはサーバーからキャプチャイメージをロードし、準備完了時に をWPFフォームのImageに割り当てます。私は次のように、私のためのスレッドを実行するために のBackgroundWorkerを使用しています:

ウィンドウには、以下が呼び出され、ロードされているとき:

BackgroundWorker _bgWorker = new BackgroundWorker(); 

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

GetCaptchaImage機能は画像 をロードし、かなり単純です別のスレッドで:

BitmapSource _tempBitmap = GetCaptchaFromServer(); 

私は現在、私はを呼んで、私の窓のイメージソースに、この ImageSourceはを割り当てるためにディスパッチャを起動する方法を知っておく必要があります次のように_tempBitmapをロードした後ディスパッチャ:CaptchaBitmapは私のイメージソースにデータバインドされ

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

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

大変お手伝いいたします。 :)

答えて

0

ちょうど不思議そうです。BackgroundWorkerクラスの代わりにDispatcherスレッドでイメージを取得して設定するのはなぜですか?

Dispatcher.Invoke(DispatcherPriority.Background, 
    new Action(() => { CaptchaBitmap = GetCaptchaFromServer(); }) 
); 
5

ただ、すべてのWPFオブジェクトのみがそれらを作成したスレッドからアクセスすることができDispatcher.Invoke

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

を呼び出す前にBitmapSource.Freezeを呼び出し、例外が(明白な理由のために)ディスパッチャであり、Freezableの後フリーズメソッドを呼び出します。

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

+0

私はこの問題の最後の1時間、私の髪を引き裂いてきました。ありがとう! –

0

@Arcturus、 私の経験から、サーバーからのダウンロードが完了するまではUIレスポンスは得られません...実際にはUIスレッドをインターヒューズしているため、ダウンロードしています...私は私のprojのカップルでこの間違いをして、UIが応答しない理由を疑問に思っています。

+0

うん、それは本当の.. thatsなぜ私は通常、バックグラウンドスレッドでは、UIスレッドは、ほとんどの注意を取得し、更新を維持する作業を行うことです。 – Arcturus

関連する問題