试试用JetBrains dotTrace Performance调试Silverlight代码

概述

在.NET平台下常用的性能调试工具有WinDBG, ANTS Performance Profiler,JetBrains dotTrace Performance,CLR Profiler等。

WinDBG比较强大,但是也是用起来较为复杂的一种。WinDBG一般采用输入命令式的方式。WinDBG能查看当前应用内存中有多少对象。每个对象的地址,对象之间的依赖关系。以及能Dump出IL等。当我们看到某个类型的对象不应该有这么多,这个时候我们可以尝试随机Dump出某个对象的依赖关系。WinDBG功能强大在张银奎的《软件调试》一书中有详细的介绍。

ANTS Performance Profiler 和dotTrace 差不多都是采用拍摄内存快照的方式。这里主要介绍dotTrace在Silverlight中使用方法。

dotTrace使用方法

1. 下面使用dotTrace 4.0+VS2010调试Silverlight。dotTrace4.0可集成于VS2010中如图:

clip_image002

2.启动VS2010调试模式会启动VS2010虚拟IIS WebDev.WebServer40 clip_image004

3.点击VS菜单dotTraceàProfile Applicationà选择Silverlight Application 点击OKà输入我们要运行的URL地址 点击OK。

clip_image006clip_image008

clip_image010

4.dotTrace这样就启动了,默认是开启监控状态,即你现在的操作过程都会被dotTrace记录下来。如果整个过程被记录下来文件的内容会比较大,不便于我们查找我们需要的东西。点击clip_image012可以删除本段快照记录,点击clip_image014可以启动一个新的快照。点击clip_image016可以获取本段监控的文件并且打开文件。一同事说当在DataFrom(ToolKit控件)中编辑了数据后,当前Entity的一个属性State会改变成其它值,而且调试了半天没跟踪到时哪里改变了这个值。(由于代码封装层数过多运行的地方好多又是异步的,并且Entity是动态生成的。也许可能改变值的地方不是我们这边写的代码。所以给调试带来了许多的困难。我们项目组有一层代码是别的部门封装的,我们自己也无法调试进去,总之同事确定不是他自己这边的代码改变了这个属性的值)于是我们就将数据操作然后点击空白处这个过程监控下来。

5.如下图是dotTrace监控下来的一段快照,左边有Tread Tree,CallTree,Plain List,Hot Spots

image

。按Ctrl+F可以查找Class 和Function。

分析:当RowState的值变成Deleted了,一定会设置Entity的RowState,在.NET运行时候对属性的访问会生成一个set_属性名 这样的一个方法,输入set_RowState。果然clip_image020找到了set_RowState方法, 双击set_RowState会跳到这个方法的Call Tree

clip_image022

分析:我们可以清晰的看到在DataFromde CommitEdit-> QueryablecollectionView的CommitEdit->OnCollectionChanged->OnCollectionChanged ->RemoveRowsForOldEntities。很有可能就是这里RemoveRowsForOldEntities的时候将RowState作为了Deleted状态了。

那么为什么QueryablecollectionView的CommitEdit会触发OnCollectionChanged事件呢,我们知道OnCollectionChanged只有在集合Remove或者Add的时候才会触发,难道QueryablecollectionView的CommitEdit做了这个动作?

下面我们反编译QueryablecollectionView的CommitEdit方法

clip_image024

clip_image026

仔细看CommitEdit方法调用了RefreshOnItemAction方法。在RefreshOnItemAction方法中当布什分组状态和QueryablecollectionView的分页状态时 有removeArgs 和addedArgs,猜测这里肯定是先Remove了一个Entity,然后再Add了一个Entity。我们再看RaiseCollectionChangedOnItemAction方法,基本可以确定是Add一下然后在Remove了一下

clip_image028

上述例子我们只是用了dotTrace一个小小的功能,看它的CallTree。DotTrace主要是用来调试性能的,我们可以在CallTree上看到每个方法调用所占时间的百分比。当然我们这里也不能一定确认RowState属性的值是因为这里导致,最少现在我们知道这里可能导致这个问题。下面我们可以在自己的代码中针对这几处调试。调试往往是先定位到几处可能发生问题的地方,然后逐一排除。工具只能帮我们定位到可能发生问题的地方。如果不先缩小我们调试的范围。由于运行的代码过多,往往给调试带来巨大的工作量之后可能还不能找到问题的根源。我们这里主要是简单的介绍DotTrace工具的初步使用方法。

转载于:https://www.cnblogs.com/ForrestZhang/archive/2010/12/22/1914158.html