3

私はフィールドを宣言しました:

WriteableBitmap colorBitmap;

次に、何かを行う単純なスレッドを作成しました。

private void doSomething()
{
    // ... bla bla bla
    colorBitmap = new WriteableBitmap(/* parameters */);
    myImage.Source = colorBitmap; // error here:S
}

Windows_Loadedイベントで、新しいスレッドを宣言して開始しました。

private void window_Loaded(object sender, RoutedEventArgs e)
{
    Thread th = new Thread(new ThreadStart(doSomething));
    th.Start();
}

問題は、myImageのソースを変更できなかったことです。次のようなエラーが発生しました:

InvalidOperationExceptionは処理されませんでした。別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。

Dispatcher.Invokeを使用しようとしましたが、役に立ちませんでした...

Application.Current.Dispatcher.Invoke((Action)delegate
{
    myImage.Source = colorBitmap;
});

私はいくつかの答えを探していましたが、私のものとまったく同じケースを見つけることはできませんでした。any1は、このような問題を解決する方法を理解するのに役立ちますか(最近同じ問題が発生しましたが、他のスレッドが所有しているため、メソッドを呼び出すことができませんでした)。

4

1 に答える 1

9

コードには2つの問題があります。

  1. WriteableBitmap作成したスレッドとは異なる別のスレッドからにアクセスすることはできません。それをしたい場合は、WriteableBitmap.Freeze()最初に呼び出してビットマップをフリーズする必要があります

  2. myImage.Sourceディスパッチャスレッド以外のスレッドではアクセスできません。

これにより、次の2つの問題の両方が修正されます。

private void doSomething()
{
    // ... bla bla bla
    colorBitmap = new WriteableBitmap(/* parameters */);
    colorBitmap.Freeze();
    Application.Current.Dispatcher.Invoke((Action)delegate
    {
        myImage.Source = colorBitmap;
    });
}

編集 このアプローチでは、スレッド内のどこにでもビットマップを作成および更新できることに注意してください。ビットマップがフリーズすると、変更できなくなります。その場合は、ゴミ箱に移動して新しいビットマップを作成する必要があります。

ちなみに、スレッドの更新をブロックしたくない場合は、代わりにmyImage.Source使用してくださいBeginInvokeInvoke

于 2012-06-27T13:14:36.970 に答える