2

私は Web サーバーから多くの画像を取得しようとしているので、1 秒あたり数百の要求でサーバーを過負荷にしないように、WebService で処理される少数のみを通過させます。次のコードは、画像を保存するオブジェクトと、すべてのバインディングの場所です。

ThreadStart thread = delegate()
{
    BitmapImage image = WebService.LoadImage(data);

    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
    {
        this.Image = image;
    }));
};

new Thread(thread).Start();

画像は正常に読み込まれます。画像が読み込まれている間、UI はスムーズに動作しますが、this.Image = image呼び出されることはありません。行を使用Dispatcher.CurrentDispatcher.Invoke(..)すると呼び出されますが、画像の設定には機能しません。ディスパッチャがアクションを呼び出さないのはなぜですか?

4

2 に答える 2

3

ワーカー スレッドで作成BitmapImageしたため、WPF スレッドによって所有されていません。たぶん、このコードは問題を解決するのに役立ちます:

投稿したコード

ThreadStart thread = delegate()
{
    BitmapImage image = WebService.LoadImage(data, Dispatcher.CurrentDispatcher);

    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
    {
        this.Image = image;
    }));
};

new Thread(thread).Start();

WebService.LoadImage「うまくいく」ように自分を変える方法

BitmapImage LoadImage(object data, Dispatcher dispatcher)
{
    // get the raw data from a webservice etc.
    byte[] imageData = GetFromWebserviceSomehow(data);

    BitmapImage image;

    // create the BitmapImage on the WPF thread (important!)
    dispatcher.Invoke(new Action(()=>
    {
        // this overload does not exist, I just want to show that
        // you have to create the BitmapImage on the corresponding thread
        image = new BitmapImage(imageData);
    }));

    return image;
}
于 2012-12-29T16:47:10.457 に答える
1
System.Object
    |-> System.Windows.Threading.DispatcherObject
        |-> System.Windows.DependencyObject
            |-> System.Windows.Freezable
                |-> ... 
                    |-> System.Windows.Media.Imaging.BitmapImage

BitmapImageはスレッド アフィニティです。したがってthis、コントロールとBitmapImageオブジェクトは同じスレッドで作成する必要があります。また、画像をフリーズすることもできますが、役に立たないようです。

BeginInvokeWPF によって処理されるため、エラーは明らかになりません。WPF トレースの設定方法については、MSDN を参照してください。

WPF はシングル スレッドです。すべてのスタッフが説明した WPF に関する本を読んでください。

于 2012-12-29T16:18:40.700 に答える