wpf在后台线程中载入图像

本文介绍了一种在WPF应用程序中使用后台线程加载图片的方法,解决了UI停滞的问题。通过利用BitmapImage的Freeze方法,使得对象可以在多个线程间共享。

这两天在学习wpf的过程中遇到一个问题,当读取很多图像的时候我希望在后台的另一个线程中进行,否则UI会停滞。然而BitmapImage类只能在创建的类中访问,否则会抛出InvalidOperationException。当我在后台线程中创建并初始化BitmapImage后将其赋值给一个image控件,便会因无法访问Image控件而抛出异常。调用image.BeginInvoke()方法在主线程中赋值,又会因无法访问BitmapImage而抛出异常。最后把MSDN里BitmapImage的成员全看了一遍,发现一个Freeze()方法,它的描述是这样的:

 

引用:使当前对象变为不可修改并将其 IsFrozen 属性设置为 true。 (继承自 Freezable。)

 

 

于是抱着试试看的心情点了一下Freezable类,发现有如下说明 :

 

引用:

派生自 Freezable 的类可以获得以下功能:

  • 特殊状态:只读(冻结)状态和可写状态。

  • 线程安全性:可以在线程之间共享冻结的 Freezable 对象。

  • 详细的更改通知:与其他 DependencyObject 对象不同,Freezable 对象可在子属性值更改时提供更改通知。

  • 便于克隆:Freezable 类已经实现了多种生成深层克隆的方法。

 也就是说只要将一个对象Freeze(),便能在线程间共享,而且能提高性能。于是在后台线程中将BitmapImage Freeze()后再交给Image控件,再也没有抛出异常了。

 最终代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
1<Window x:Class="WpfApplication2.Window1"
2    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
5    <Grid>
6        <Image Margin="14,18,19,22" Name="image1" Stretch="Fill" />
7    </Grid>
8</Window>
9

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5using System.Windows;
 6using System.Windows.Controls;
 7using System.Windows.Data;
 8using System.Windows.Documents;
 9using System.Windows.Input;
10using System.Windows.Media;
11using System.Windows.Media.Imaging;
12using System.Windows.Navigation;
13using System.Windows.Shapes;
14using System.Threading;
15
16namespace WpfApplication2
17ExpandedBlockStart.gifContractedBlock.gif{
18ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
19    /// Window1.xaml 的交互逻辑
20    /// </summary>

21    public partial class Window1 : Window
22ExpandedSubBlockStart.gifContractedSubBlock.gif    {
23        public Window1()
24ExpandedSubBlockStart.gifContractedSubBlock.gif        {
25            InitializeComponent();
26        }

27
28        private void Window_Loaded(object sender, RoutedEventArgs e)
29ExpandedSubBlockStart.gifContractedSubBlock.gif        {
30            ThreadPool.QueueUserWorkItem(new WaitCallback(LoadImage));
31        }

32
33        private void LoadImage(object state)
34ExpandedSubBlockStart.gifContractedSubBlock.gif        {
35            BitmapImage myBitmapImage = new BitmapImage();
36            myBitmapImage.BeginInit();
37            myBitmapImage.UriSource = new Uri(@"E:\marisa2.png");
38            myBitmapImage.DecodePixelWidth = 400;
39            myBitmapImage.EndInit();
40            myBitmapImage.Freeze();
41            
42            image1.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,new Action(() =>
43ExpandedSubBlockStart.gifContractedSubBlock.gif            {
44                image1.Source = myBitmapImage;
45            }
));
46        }

47
48    }

49}

50

 

posted on 2009-02-13 15:00 clowwindy 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/clowwindy/archive/2009/02/13/1390060.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值