当前位置:  开发笔记 > 编程语言 > 正文

使用WPF在C#中异步加载BitmapImage

如何解决《使用WPF在C#中异步加载BitmapImage》经验,为你挑选了1个好方法。

使用WPF在C#中异步加载BitmapImage的最佳方法是什么?似乎存在许多解决方案,但是存在标准模式还是最佳实践?

谢谢!



1> 小智..:

我只是在研究这个并且不得不投入我的两分钱,虽然在原始帖子后几年(以防万一其他人来寻找我正在研究的同样的事情).

我有一个Image控件,需要使用Stream在后台加载它的图像,然后显示.

我一直遇到的问题是BitmapSource,它的Stream源和Image控件都必须在同一个线程上.

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

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

事实证明,一行代码将使这些工作中的任何一个:

//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();


BackgroundWorker在System.dll的System.ComponentModel命名空间中定义,而不是在Windows窗体中定义,因此可以将它用于WPF.
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有