locked
Updating a BitmapSource from background thread RRS feed

  • Question

  • I wish to achieve a good performance updating an image, so I've done a custom control that receives all the required variable to create it by xaml and then reverese to local variable.

    Furthermore, instead of binding the image source I've decided to bind (one time mode) the whole image, in order to update its image source from the background thread and avoid the binding .

    The problem is that I receive this error when I assign the built bitmap to ImageSource

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

    Unfortunately calling the dispatcher invoker consumes a lot of performance, while the dispatcher timer is also really slow.

    What can I do to assign image source without having thread problems?


    • Edited by Zenon66 Sunday, October 28, 2012 1:35 PM
    Sunday, October 28, 2012 1:32 PM

Answers

  • ...

    Furthermore, instead of binding the image source I've decided to bind (one time mode) the whole image, in order to update its image source from the background thread and avoid the binding .

    ...snip...

    What can I do to assign image source without having thread problems?

    I believe the answer IS to use binding. Dispatcher is the only way to access UI controls. PropertyChanged events are a way around this problem.

    Also, the dispatcher has an overload for DispatcherPriority which may help.

     

    Regards,
    Pete


    #PEJL

    • Proposed as answer by jony feldman Monday, November 5, 2012 3:41 PM
    • Marked as answer by Jie Bao Friday, November 9, 2012 6:48 AM
    Sunday, October 28, 2012 6:53 PM

All replies

  • ...

    Furthermore, instead of binding the image source I've decided to bind (one time mode) the whole image, in order to update its image source from the background thread and avoid the binding .

    ...snip...

    What can I do to assign image source without having thread problems?

    I believe the answer IS to use binding. Dispatcher is the only way to access UI controls. PropertyChanged events are a way around this problem.

    Also, the dispatcher has an overload for DispatcherPriority which may help.

     

    Regards,
    Pete


    #PEJL

    • Proposed as answer by jony feldman Monday, November 5, 2012 3:41 PM
    • Marked as answer by Jie Bao Friday, November 9, 2012 6:48 AM
    Sunday, October 28, 2012 6:53 PM
  • This is odd.

    The same operation with WinForms costs me just a 2-3 % of resources, while here it's about 60 - 70%.

    I think I haven'  find the best solution yet

    Sunday, October 28, 2012 8:49 PM
  • To make things more clear, this is what I do:

    public class FooImage : Image { DispatcherTimer _timer = new DispatcherTimer(DispatcherPriority.SystemIdle);

    // Timer tick updates every 300 ms void _timer_Tick(object sender, EventArgs e) { // code for creating a System.Drawing.Bitmap ImageSource imgSrc = ImageToBitmapImage(bmp); // till here performance are good. // assigning the source to image raise CPU to 60-70% this.Source = imgSrc; } public static ImageSource ImageToBitmapImage(Image bmp) { BitmapImage bImg = new BitmapImage(); if (bmp != null) { using (MemoryStream memory = new MemoryStream()) { bmp.Save(memory, ImageFormat.Png); memory.Position = 0; bImg.BeginInit(); bImg.StreamSource = memory; bImg.CacheOption = BitmapCacheOption.OnLoad; bImg.EndInit(); } } return bImg; } }


    As you can see no binding is used during operation. Is it possible that updating an image every 1/3 second is so expansive ?

    Monday, October 29, 2012 9:26 AM
  • try to use bindings as "xaml guy" said i think it will work better
    Monday, October 29, 2012 9:53 AM