Silverlight内存释放、性能提升及源文件保护(续) - 面向对象网,web开发,silverlight,学习,对象 - 面向对象技术开发

面向对象技术开发

会员投稿 投稿指南 站长资讯通告:
您的位置: 首页 > Web开发 > Silverlight > 正文

Silverlight内存释放、性能提升及源文件保护(续)

来源: www.bianceng.cn 阅读:

在第八节、第三节、第二节中,我曾向大家详细的分析了Silverlight在内存释放、性能提升及源码保护等 方面的相关处理。随着游戏教程的不断深入,自身各方面经验的不断累积、总结与升华;至今日,我对这3方 面的认识又有了更深层次的理解。作为前3篇的续,本节我将继续对Silverlight开发技巧进行深度挖掘,用行 动来证明对技术的追求永不止步。

一)内存释放

首先,希望大家强烈认识到Silverlight程序是托管的,除特别明显或强烈的需要外(例如OpenFileDialog 、SaveFileDialog等继承自IDisposable接口的类),望大家不要轻易介入GC.Collect(),这是微软设计.NET的 初衷,我们仅能且必须做的就是:信任。

其次,需要所有精通.NET开发语言的朋友再次确认自己是否对数据类型有深刻理解。以C#为例,在编写代 码时尤其要分清值类型与引用类型,包括它们的定义、组成及原理。因为值类型对象在赋值后其内存可以很快 释放掉。以Struct(结构)和Class(类)为例,如果不需要实现继承,使用值类型可接口的Struct将得到比Class 更高的性能。另外,在书写类内部时,尽量不要使用私有类对象;同时要注意如果一个类一直被其他类所引用 着,内存同样无法被释放。在与其他Silverlight开发者交流中经常会听到类似这样的抱怨:Storyboard太耗 内存了,Storyboard性能太低下了,Storyboard太……无语了。俗话说:成也萧何,败也萧何,这些症状均是 Storyboard类被滥用的结果。这里的“滥”包含两层意思:1、不会用;2、用过度。一个好工具要物尽其用, 则必须精通它的原理与细节。Storyboard是否无意中被放进了循环里?是否出现了委托泄漏?Storyboard在 Completed后其他对象是否仍在引用着它?Storyboard是否忘记停止啦?等等。包括DispatcherTimer也一样, Silverlight在为我们制作各种流畅动画效果提供便利工具的同时,我们是否也应该让代码做到更严谨些呢?

小结:Silverlight内存释放最终还得看自己,简单说就是:只要够精通,够专业,没有释放不掉的内存。 作者也在朝这个方向努力着。

二)性能提升

1)在第三节中我曾有提到利用BackgroundWorker在后台线程中执行相对耗时的操作进而减少Silverlight 界面线程的负担。其实,我们同样还可以通过异步的方式提高画面的流畅度,比如:

this.Dispatcher.BeginInvoke(() => {
     //TODO…
   });

Dispatcher是WPF/Silverlight机制的核心,深入理解它有助你编写更高性能的代码。

2)在动画及游戏开发中尽量减少不必要的呈现、重绘(例如在Canvas.SetLeft前先判断Canvas.GetLeft是 否与Value值相同);隐藏掉不在屏幕中的图象载体(obj.Visibility = Visibility.Collapsed),对图象进行 切割,减少窗体中的图片数量,对相同或类似图片尽量做到复用,监控好委托的订阅与取消订阅(订阅N次将执 行N次操作,如果发生在循环里极易造成内存泄露甚至程序崩溃,请初学者认识到这点)等等,虽然均是些细节 ,但效果往往却非常明显。

3)调整好最大FPS,Silverlight中的MaxFrameRate可以通过 Application.Current.Host.Settings.MaxFrameRate 进行动态调整,此技巧在游戏及动画设计中如果能应用 得当,有时会取得意想不到的效果。

4)Silverlight中制作动画常用的方法大致有5种:DispatcherTimer、Storyboard、Thread、 CompositionTarget.Rendering、Storyboard as Trigger。5 methods to create game loop: which is the best?这篇文章中很详细的列举及讨论了该5种方法在性能、稳定性等各方面的比较,结论加个人体会大致上是 DispatcherTimer与Storyboard占据了Top2的地位。下面是该演示的Demo及其作者的总结翻译(原文在Demo的链 接中,仅供大家参考,个人感觉有些评价并不太符合实际),为大家今后制作Silverlight动画提供更好的依据 :

\

方法 优点 弊端 什么时候使用合适?(建议) 什么时候最好不要
使用(建议)
DispatcherTimer   相对稳定 最小识别率约15毫秒(个人理解为
频率过快将导致跳帧或无效,即极限
为15豪秒)
缓慢移动的物体,
联合Storyboard一同控制动画
在处理一个移动
非常快的物体对象时,
建议使用
Storyboard as Trigger

CompositionTarget
.Rendering提高帧速率。
Storyboard 平滑的动画 没有复杂的运动效果,例如行星、
游戏等的无规则Path运动
(这结论也太…… ^^||)
简单的移动模式方面 如果想通过更多的
后台代码去控制动画,
建议还是使用
CompositionTarget
.Rendering。
(这建议真 的很晕……)
Thread 基于线程,均衡的每帧
运行。在多核中效果更好
在很短的间隔内不稳定(2帧间) 需要大量计算,耗CPU的处理 如果你的电脑只有
1个CPU,或者需要
更快的动画效果,
还是请选择其他的方法
CompositionTarget
.Rendering
非常稳定,保证会运行到位 无法进行细节控制,因为频率
是固定的,基于画面刷新触发,
公式:1000/<frames-per- secspecified-
in-html>
[msec]
复杂的逻辑,如游戏中的一些
循环等逻辑(原话看得不是很懂……)
一些琐碎的处理,
例如游戏中的云朵
从左飘到右, 则建议
使用Storyboard代替。
Storyboard as Trigger 类似DispatcherTimer,在300FPS下运行流畅 和DispatcherTimer一样 类似DispatcherTimer 和DispatcherTimer
一样

三)源文件保护

在第二节中我分析了几种保护Silverlight源码的方法,代码混淆是最终解决方案。但随着Silverlight应 用越来越广泛且丰富,以增强用户体验为目标,我们通常会将图片等素材从xap压缩包中分离出来,作为动态 资源进行按需下载。然而这将直接导致所有素材裸露于Temporary Internet Files中,源码保住了,但是又泄 露了素材资源,结果is so bad。

解决方案:以下载图片为例,在Silverlight游戏设计教程第九节结尾我曾详细的讲解了BitmapImage的诸 多细节,将BitmapImage的CreateOptions属性设定为BitmapCreateOptions.None,图片将分成两份,一份存于 内存中,一份存于Temporary Internet Files;然后再利用第二节方法一提到的禁止关键文件或文件夹页面缓 存,我们将让用户永远也无法触摸到Silverlight中的任何图片素材,而所有资源素材一经下载后将永驻内存 直至页面关闭。不过副作用还是有的,没了浏览器缓存,每次进入游戏都需要重新下XAP及相关资源;图片呈 现方面也稍微有些延迟。当然了,每次2、3百K的XAP+按需获取资源所增加的服务器流量负荷相对于完全泄露 项目资源来说一毛九牛。

以上为近阶段个人在Silverlight开发方面的心得,希望能对大家有所帮助,如有不对之处还望指正。

Tags:
相关文章列表: