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

在什么情况下,冻结WPF对象会大大提高性能?

如何解决《在什么情况下,冻结WPF对象会大大提高性能?》经验,为你挑选了3个好方法。

WPF中的许多类型都源于Freezable.它为可变POCO对象提供了不变性,并且显然可以在某些情况下提高性能.

有没有人发现在他们的WPF应用程序中冻结对象大大提高了性能?如果是这样,那么哪些项目在冻结时会产生最大的性能差异?

(请注意,我也发布了类似但不同的问题)



1> 小智..:

您可能对我使用Freezable的经历感兴趣:

我曾经使用muPdf编写了一个PDF查看器,它渲染了我用WPF渲染的位图.有助于提高性能的是我可以在后台线程上呈现页面位图,冻结它们,然后将它们传递给UI线程.WPF不会复制图像以冻结它是很好的,但是在后台线程上完成所有这些准备的能力对我来说是关键的好处.

根据我的理解,所有视觉效果都需要被冻结,以便WPF渲染线程可以安全地呈现它们.如果渲染大量未冻结的视觉效果,当WPF呈现它们时,它们将被克隆到冻结的视觉效果中.如果事先冻结静态位图,WPF只能与渲染线程共享指针而不进行克隆.如果WPF不知道对象是否从上次渲染时更改,则未冻结的对象甚至可能会被重复复制.冻结的对象消除了所有这些复制的需要.



2> CSharper..:

如果使用Image控件(而不是使用Freeze方法),可能会发生这些潜在的内存泄漏:

a)您使用BitmapImage作为图像源并且不释放BitmapImage:

static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",UriKind.RelativeOrAbsolute));
m_Image1 = new Image();
m_Image1.Source = bi1; 
//bi1.Freeze() 
//if you do not Freeze, your app will leak memory.
MyStackPanel.Children.Add(m_Image1);

b)您将多个BitmapImage指定为Image源,并且不释放您使用的所有BitmapImage(类似于(a)).这个在.Net 3.5中引入:

static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",
UriKind.RelativeOrAbsolute));
static BitmapImage bi2 = new BitmapImage(new Uri("Bitmap2.bmp",
UriKind.RelativeOrAbsolute));
bi2.Freeze();
m_Image1 = new Image();
//bi1.Freeze() 
//even though you are really using bi2 for Image Source, 
//you also need to Freeze bi1 it to avoid leak 
m_Image1.Source = bi1;  // use un-frozen bitmap, which causes the leak
m_Image1.Source = bi2;  // use frozen bitmap
MyStackPanel.Children.Add(m_Image1);

来源:WPF表演



3> Manish Basan..:

虽然你已经接受了答案,但只是想记录一个不同版本的答案,这些答案对我有所帮助.

来自MSDN(次要编辑):

如果要修改对非托管低级资源(例如:Brush)的控制保持引用,则每次修改都必须重新生成那些低级对象!

freezable类使刷子能够找到相应的生成的低级对象,并在更改时更新它们.启用此功能后,刷子会被称为"解冻".

freezable的Freeze方法使您可以禁用此自我更新功能.您可以使用此方法使画笔变为"冻结"或不可修改.因此,提高性能.

并且,解释用法的代码:

            Button myButton = new Button();
            SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);

            if (myBrush.CanFreeze)
            {
                // Makes the brush unmodifiable.
                myBrush.Freeze();
            }                
            myButton.Background = myBrush;        
            if (myBrush.IsFrozen) // Evaluates to true.
            {
                // If the brush is frozen, create a clone and modify the clone.
                SolidColorBrush myBrushClone = myBrush.Clone();
                myBrushClone.Color = Colors.Red;
                myButton.Background = myBrushClone;
            }
            else
            {
                // If the brush is not frozen, it can be modified directly.
                myBrush.Color = Colors.Red;
            }

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有