使用WPF在C#中异步加载BitmapImage [英] Asynchronously Loading a BitmapImage in C# using WPF

查看:73
本文介绍了使用WPF在C#中异步加载BitmapImage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用WPF在C#中异步加载BitmapImage的最佳方法是什么?

What's the best way to asynchronously load an BitmapImage in C# using WPF?

推荐答案

我只是调查这个问题,不得不投入两分钱,尽管最初的帖子过了几年(以防其他人找寻)我正在调查的同一件事).

I was just looking into this and had to throw in my two cents, though a few years after the original post (just in case any one else comes looking for this same thing I was looking into).

我有一个图片控件,需要使用 Stream 将其图片加载到后台,然后显示.

I have an Image control that needs to have it's image loaded in the background using a Stream, and then displayed.

我一直遇到的问题是 BitmapSource ,它的 Stream 源和 Image 控件必须位于同一位置线程.

The problem that I kept running into is that the BitmapSource, it's Stream source and the Image control all had to be on the same thread.

在这种情况下,使用Binding并将其设置为IsAsynch = true将引发跨线程异常.

In this case, using a Binding and setting it's IsAsynch = true will throw a cross thread exception.

BackgroundWorker非常适合WinForms,您可以在WPF中使用它,但是我宁愿避免在WPF中使用WinForm程序集(不建议对项目进行膨胀,这也是一个很好的经验法则).在这种情况下,这也应该引发无效的交叉引用异常,但是我没有对其进行测试.

A BackgroundWorker is great for WinForms, and you can use this in WPF, but I prefer to avoid using the WinForm assemblies in WPF (bloating of a project is not recommended, and it's a good rule of thumb too). This should throw an invalid cross reference exception in this case too, but I didn't test it.

结果证明,一行代码可以完成以下任何一项工作:

Turns out that one line of code will make any of these work:

//Create the image control
Image img = new Image {HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, VerticalAlignment = System.Windows.VerticalAlignment.Stretch};

//Create a seperate thread to load the image
ThreadStart thread = delegate
     {
         //Load the image in a seperate thread
         BitmapImage bmpImage = new BitmapImage();
         MemoryStream ms = new MemoryStream();

         //A custom class that reads the bytes of off the HD and shoves them into the MemoryStream. You could just replace the MemoryStream with something like this: FileStream fs = File.Open(@"C:\ImageFileName.jpg", FileMode.Open);
         MediaCoder.MediaDecoder.DecodeMediaWithStream(ImageItem, true, ms);

         bmpImage.BeginInit();
         bmpImage.StreamSource = ms;
         bmpImage.EndInit();

         //**THIS LINE locks the BitmapImage so that it can be transported across threads!! 
         bmpImage.Freeze();

         //Call the UI thread using the Dispatcher to update the Image control
         Dispatcher.BeginInvoke(new ThreadStart(delegate
                 {
                         img.Source = bmpImage;
                         img.Unloaded += delegate 
                                 {
                                         ms.Close();
                                         ms.Dispose();
                                 };

                          grdImageContainer.Children.Add(img);
                  }));

     };

//Start previously mentioned thread...
new Thread(thread).Start();

这篇关于使用WPF在C#中异步加载BitmapImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆