“不要频繁获释对象”的略微随笔

“不要频繁获释对象”的略微随笔

【题外话】

前大部分岁月还在用Visual Studio
2008举行开发,虽然也接触起来过代码分析,但是同看无异老串内容,尤其是如出一辙生失误针对命名的提议,就坚决关闭了。这次见习使用的Visual
Studio
2012,发现代码分析默认去丢了多情节,显示的啊都是比较根本并欲改进的地方,所以啊都信以为真切磋了一晃。

 

【文章索引】

  1. 题材跟解决办法
  2. 胡这么去开
  3. 连锁链接

 

【一、问题和解决方式】

相应有人会写如下的代码吧,为了释放资源,我们把开拓的物还关门掉,貌似没有呀问题。

 1 FileStream fs = null;
 2 StreamReader sr = null;
 3 
 4 try
 5 {
 6     fs = new FileStream(@"F:\test.txt", FileMode.Open, FileAccess.Read);
 7     sr = new StreamReader(fs);
 8 
 9     String content = sr.ReadToEnd();
10 }
11 finally
12 {
13     if (sr != null)
14     {
15         sr.Close();
16     }
17 
18     if (fs != null)
19     {
20         fs.Close();
21     }
22 }

当,喜欢用using的校友也说不定会见写如下的代码:

1 using (FileStream fs = new FileStream(@"F:\test.txt", FileMode.Open, FileAccess.Read))
2 {
3     using (StreamReader sr = new StreamReader(fs))
4     {
5         String content = sr.ReadToEnd();
6     }
7 }

可是及时点儿种代码如果运用代码分析会起啊情况吗,如下图。

个人档案 1

于好玩的凡,这里提醒的是“不承诺本着一个目标往往调用
Dispose”,为什么会是“一个靶”呢?

由此阅读MSDN中之CA2202(链接以文后),我们得以查及由是这般的,“某个方法实现所涵盖的代码路径可能引致对平对象往往调用
IDisposable.Dispose 或与 Dispose 等效的章程(例如,用于某些品种的
Close()
方法)”,MSDN中一直给来了缓解措施就是是绝不关StreamReader,而是直接关闭FileStream。

 

【二、为什么如此夺做】

MSDN给来之不二法门为什么要如此做也?出于好奇心,首先以上述的代码单步调试一下:

个人档案 2

当履完毕StreamReader的Close之后,StreamReader的BaseStream指向了null,同时fs也变成了不可知读取,但fs不是null。

下一场我们之所以Reflector找到StreamReader的落实(在mscorlib.dll文件被)如下:

 1 public override void Close()
 2 {
 3     this.Dispose(true);
 4 }
 5 
 6 protected override void Dispose(bool disposing)
 7 {
 8     try
 9     {
10         if ((this.Closable && disposing) && (this.stream != null))
11         {
12             this.stream.Close();
13         }
14     }
15     finally
16     {
17         if (this.Closable && (this.stream != null))
18         {
19             this.stream = null;
20             this.encoding = null;
21             this.decoder = null;
22             this.byteBuffer = null;
23             this.charBuffer = null;
24             this.charPos = 0;
25             this.charLen = 0;
26             base.Dispose(disposing);
27         }
28     }
29 }

StreamReader在履Close时竟然执行了this.stream(BaseStream)的Close,然后将BaseStream再针对null,这就算解决了之前为什么提示不要频繁获释
一个
对象,其实是StreamReader的Close已经出狱了一致次等而已。当然,不仅仅是StreamReader个人档案是这样子,StreamWriter、BinaryReader等等也都是这样子的。

可,为什么MSDN的事例让的凡关门流一旦无是关门读取器呢?

阅读了网上也尚无找到权威的素材,所以个人总结了几乎点如下仅供参考:

1、关闭StreamReader等其实已经关门了那个BaseStream,但爱使开发者误以为BaseStream没有关而延续利用导致抛来十分,所以关闭最基础的流会更好把。

2、StreamReader等自己并没有运用非托管的情节,所以啊不管需积极履行Close,让GC去做就哼了。

 

【三、相关链接】

1、CA2202:不要反复纵对象:http://msdn.microsoft.com/zh-cn/library/ms182334(v=vs.110).aspx

admin

网站地图xml地图