【续】WPF支持GIF的各种方法

原创 2012年01月26日 11:19:57

前一篇介绍了我的GifImage与其他人的GIF支持实现,以及对比;这一篇再进行另一项对比。


本文主要是自我记录,对读者的意义可能不大。在前文的基础上,我修改了GifImage,使其支持从两种来源获得gif图像。一是URI,二是Stream。另外,我还对GifImage进行了优化,做了很多测试保证反复创建GifImage,内存不会暴增。(事实上可以保持稳定)

因为GifImage内部使用了(有)timer,timer事件中有一项事件处理函数是GifImage里的一个方法。所以两者循环依赖,导致都不能被垃圾回收器回收,导致内存不能释放。

解决方法是显式销毁timer。比如GifImage实现IDisposable接口,在Dispose方法里取消订阅timer事件(,并设置timer=null,非必要)。要理解显式销毁的含义,就是比如说创建了GifImage,加入到WPF的StackPanel里,不用了的时候要stackPanel.Chilhren[i].Dispose(),再Clear()。

这里学到的是,不仅仅当类字段中有IDisposable成员(FxCop能检查此情况),或有非托管资源时,该类需要实现IDisposable接口;当类订阅了别人的事件时,也应该实现IDisposable接口。另外,推荐大家读一读Stephen Cleary的文章《IDisposable: What Your Mother Never Told You About Resource Deallocation》。他列举了IDisposable的坏处,反对微软的Dispose模式(即Dispose调用虚方法Dispose(bool disposing)),然后自己提出个用来实现IDisposable接口的更好的方案——我觉得他的方案更简洁更易于理解。

话说回来,刚才说GifImage有两个属性UriSource和StreamSource,分别从指定的Uri或Stream获得GIF图像。这么设定是因为在我的程序里,同一GIF图像会在多处显示,这样的话用同一个StreamSource赋值可能——所以需要试验——会减少内存占用。

与此相关的一点是BitmapCacheOption枚举,解析GIF时需要用到,它可能会影响性能。我本来想一份Stream,多个GifImage使用;试想如果那份Stream又被各个GifImage缓存起来了,那内存不是根本没有节省?还不如用UriSource呢!——所以也需要试验。

试验设计

获得GIF图片的途径有两种,URI和Stream;缓存方式有三种,OnDemand、OnLoad和None。所以2×3=6,共进行6次试验。试验结果输出到控制台,利用cmd重定向命令可以写入文本文件,再导入电子表格,统计、绘图。

测量工具

测CPU占用率,用的经我改造的Ben Watson的CpuUsage类

测私有内存和工作集,用的是PerformanceCounter。

读者可能问为什么测CPU不用PerformanceCouter。因为在我的电脑上,cpuCouter = new PerformanceCouter("Process", "% Processor Time", process.ProcessName),然后GetValue()行为怪异。往往取出的值都是0,而明显Process Explorer显示的值不是0;有时又爆高。

读者可能问为什么测私有内存和工作集不用Process.WorkingSet64之类的。它们确实能给出值,但经过多次试验,还是PerformanceCouter给出的值比较接近Process Explorer。(我不是说Process Explorer的值是绝对准确的。)


具体过程不述,直接看结果。




可以发现useUri=false的,普遍内存占用比较低。然后useUri=true中,不同的CacheOption对内存占用的影响看不太出来,于是再计算其他指标。


测试配置 useUri=False; CacheOption=OnDemand
  CPU 私有内存 工作集 Collected
平均 55 70738 67199


72460 68428
         
方差 7.45 2,910,746 3,208,384  


测试配置 useUri=False; CacheOption=OnLoad
  CPU 私有内存 工作集 Collected
平均 55 70861 66626


71392 67764 4860
         
方差 9.34 3,464,841 7,504,836  

测试配置 useUri=False; CacheOption=None
  CPU 私有内存 工作集 Collected
平均 55 70713 67573


70744 68384 4860
         
方差 10.44 3,086,858 4,010,879  

这就明显了,CacheOption=OnDemand的,cpu、私有内存、工作集占用最稳定,平均值也较小。


所以,当同一GIF图片要在WPF里的多处显示时,应当用StreamSource,且CacheOption=OnDemand。CacheOption.Default目前等于CacheOption.OnDemand。


爱让一切都对了

2012年1月26日

WPF播放GIF控件完整代码

WPF拥有很强的界面设计能力,可以很方便的做出非常漂亮的界面。但有个问题,WPF没有自己的播放GIF的控件。这让很多想在界面播放动态动画的人不得不使用视频来代替。WPF就真的不能播放GIF动图了吗?当...
  • Libby1984
  • Libby1984
  • 2016年09月14日 09:38
  • 2921

【C#】wpf添加gif动图支持

1.nuget里下载WpfAnimatedGif包,然后安装。 2.添加WpfAnimatedGif包的命名空间:xmlns:gif="http://wpfanimatedgif.codeplex.c...
  • catshitone
  • catshitone
  • 2017年06月08日 17:21
  • 1665

WPF 如何显示gif

最近碰到了要显示表情的需求,而表情刚好是gif的图片。 于是用了Image试了下,发现不行,只会显示第一帧,然后上网查了下资料,大致有这么几种方法,都可以实现。 第一种: 使用Winfrom里面的pi...
  • wcc27857285
  • wcc27857285
  • 2016年11月01日 09:52
  • 2431

【2012.12.18更新】WPF支持GIF的各种方法

2012.12.18更新:修复下载链接 已知WPF的Image元素只能显示GIF图片的第一帧,而MediaElement不能加载作为资源或内嵌的资源的GIF图片,所以网上有几种实...
  • gqqnb
  • gqqnb
  • 2012年01月21日 19:35
  • 11762

WPF使用MediaElement显示gif图片

使用MediaElement来显示gif图片,封装控件代码如下: Xaml:
  • SANYUNI
  • SANYUNI
  • 2017年06月22日 17:12
  • 397

WPF中GIF不动的问题解决方案。

WPF很强大,但是当WPF的image控件遇到gif时就只读了图片的第一帧,很好很强大! WPF不屑于gif的简单动画! 但是这对程序员来说不大爽啊!急得我眼泪都下来了! 幸好WPF里有Medi...
  • wangsui99
  • wangsui99
  • 2011年08月27日 20:40
  • 2455

解决XP上WPF显示gif卡的问题

初始化过程或者检测升级用到gif作为中间等待,但使用MediaElement在某些XP版本上,gif会卡着不动,去网上查了查,解决方案不少: http://www.cnblogs.com/zjoch/...
  • z2516305651
  • z2516305651
  • 2016年08月10日 14:07
  • 513

在Wpf中使用动态GIF图像的简单方法

Wpf本身的方法如果加载GIF实在是过于复杂,我们可以通过使用winform控件,减少复杂性方法一:利用winform控件 System.Windows.Forms. PictureBox pb ...
  • u012790747
  • u012790747
  • 2015年05月27日 21:26
  • 1768

《React-Native系列》35、 RN在Android下支持gif的另一种方案

在前面的文章中,我们介绍过在RN中Android如果处理Gif格式的图片。参考:http://blog.csdn.net/codetomylaw/article/details/52280828我们是...
  • hsbirenjie
  • hsbirenjie
  • 2016年09月28日 18:42
  • 3608

GIF动画图片在IE中不能正常显示的解决方法

IE和FirFox在很多地方都有着或多或少的不同,这导致在开发时需要考虑很多的特殊情况。在最近的项目中居然发现带动画的GIF图片在页面Load之后再以脚本控制的方式展现时,动画不能表现出来。在我的项目...
  • hudongge
  • hudongge
  • 2013年11月29日 16:46
  • 1269
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【续】WPF支持GIF的各种方法
举报原因:
原因补充:

(最多只允许输入30个字)