Nickon
Nickon

Reputation: 10156

Thread cannot access the object

I declared a field:

WriteableBitmap colorBitmap;

Then I created a simple thread which does something:

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

In Windows_Loaded event I declared and started a new thread:

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

The problem is that I couldn't change myImage's source. I've got an error like:

InvalidOperationException was unhandled The calling thread cannot access this object because a different thread owns it.

I tried to use Dispatcher.Invoke, but it didn't help...

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

I was searching for some answers, but never found the case exactly as mine. Could any1 help me to understand how to solve problems like this (I've had the same problem recently, but I couldn't call the method, because other thread owned it).

Upvotes: 3

Views: 1750

Answers (1)

GETah
GETah

Reputation: 21459

There are two problems with your code:

  1. You can't access the WriteableBitmap from another thread that is different than the one who created it. If you want to do that, you need to freeze your bitmap by calling WriteableBitmap.Freeze() first

  2. You can't access myImage.Source in a thread that is not the dispatcher thread.

This should fix both of these two problems:

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

EDIT Note that this approach allows you to create and update your bitmap wherever you want in your thread. Once the bitmap is frozen, it can no longer be modified in which case you should just trash it and create a new one.

On a side note, if you wish not to block your thread updating myImage.Source use BeginInvoke instead of Invoke

Upvotes: 10

Related Questions