Loading images asynchronous in C #

I am working on a C # WPF application that loads a lot of images and displays it as thumbnails. I would like to do this in a multithreaded way. So I tried to implement BackgroundWorker.

BackgroundWorker DoWork () code:

string[] files = e.Argument as string[]; foreach (string file in files) { ImageModel image = new ImageModel(); image.FilePath = file; _importWorker.ReportProgress(1, image); _imageCollectionVM.Images.Add(image); // also tried this one in ReportProgress() } 

In my XAML code, I bind to the BitmapImage ImageModel property. (AsyncState = True does not help.) Here I get this error: "DependencySource" and "DependencyObject" must be in the same thread.

 <Image Source="{Binding BitmapImage}" /> 

If I comment on this, the image seems to be imported, but I cannot access it, for example. selecting it in a ListView. In his SelectionChanged, he says then that this object has a different thread.

How to solve these problems? Thanks in advance!

+4
source share
3 answers

BackGround Worker is good imo for big tasks, but if it is something simple, like what you are doing, I would rather do it as

start with a list of images

 List<Image> Images =new List<Image>(); 

then run this

 Task.Factory.StartNew( () => { string[] files = e.Argument as string[]; foreach (string file in files) { ImageModel image = new ImageModel(); image.FilePath = file; // _importWorker.ReportProgress(1, image); this.BeginInvoke( new Action(() => { Images.Add(image); })); } }); 

There is no guarantee that I have the right amount of parentheses in this code.

+1
source

You must transfer the update to the GUI in the main thread. Basically, you can do multi-threaded loading of images from disk, but the actual GUI update should be single-threaded.

There are many ways to do this, and many stackoverflow questions address it. Here are a few to get you started.

Update user interface from background thread

Refresh BindingList <> from background theme?

Is updating pictureBox from a C # background thread evil?

How to use a BindingList for this

How do you properly update datagridview databagview from background thread

+2
source

In a similar situation, I did the following:

  • create an ImageProvider class that actually does the loading of images.
  • enable image viewmodel Bind to ImageSource in my ItemViewModel
  • let this ImageSource be lazy

    // // here is the pseudo code

    Lazy lazy = new Lazy (imageProvider.LoadImage (this.imagePath))

    // in ImageViewModel ...

    imageSource {get {return lazy.Value; }}

0
source

All Articles