0

I'm trying to update an Image in my UI from an event in a different thread. I'm using a Dispatcher (based on this question: Fire events from different thread) to do so, but still get the "The calling thread cannot access this object because a different thread owns it"-Error Message at i.Source = s;. What's the proper way of doing this?

void OnEvent(object sender, EventArgs e)
{
    ImageSource s = e.Image;
    Dispatcher.BeginInvoke((Action)(
        () => UpdateUI(myImage, s)
    ));
}

void UpdateUI(Image i, ImageSource s)
{
    i.Source = s;
}

Thanks a lot for any suggestions!

Community
  • 1
  • 1
DIF
  • 2,470
  • 6
  • 35
  • 49
  • You are dispatching on your current thread, not the UI thread. You first need to gain access to the UI Thread dispatcher. What kind of object are you dispatching from? – BatteryBackupUnit Feb 19 '14 at 12:16

3 Answers3

2

ImageSource created in background thread can't be assigned as source to UI control.

And you can access myImage.Dispatcher to get actual dispatcher associated with image control:

myImage.Dispatcher.BeginInvoke((Action)delegate       
  {
     ImageSource s = e.Image;
     UpdateUI(myImage, s);
  });

OR

call Freeze() on ImageSource before assignment. Freeze objects can be accessed across thread.

Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • 1
    Thanks, I managed to get it done using `Freeze()` and `ImageSource s = e.Image.Clone();`. Using the myImage.Dispatcher did not help anything. – DIF Feb 19 '14 at 12:49
  • Great..!! That was just in case `Dispatcher` wasn't correct. Main issue is the one which i added as bold in an answer. – Rohit Vats Feb 19 '14 at 13:33
1

You're getting this error because you ImageSource has been created on different thread then the one you want to use it on. You can fix it by calling Freeze() on your ImageSource

ImageSource s = e.Image;
s.Freeze();
dkozl
  • 32,814
  • 8
  • 87
  • 89
  • 1
    Thanks, I managed to get it done using Freeze() and ImageSource s = e.Image.Clone(); – DIF Feb 19 '14 at 12:50
0

You are dispatching on your current thread, not the UI thread. You first need to gain access to the UI Thread dispatcher. Use

Application.Current.Dispatcher.BeginInvoke(...)

instead.

Also see this question: How do I get the UI thread Dispatcher?

Community
  • 1
  • 1
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • Using `Application.Current.Dispatcher` `myImage.Dispatcher` didn't improve anything. I'm now going with `Freeze()`. Thank you! – DIF Feb 19 '14 at 12:51