2016-12-05 46 views
-1

C#关键字使用实现Idisposable它提供了一个机制,为 释放非托管资源。使用关键字和Managed UnManaged代码

现在我正想通过这个代码

string txt = String.Empty; 
     using (StreamReader sr = new StreamReader(filename)) { 
     txt = sr.ReadToEnd(); 
     } 

,并不能停止想知道,为什么使用在这个代码是用来同时的StreamReader是受管资源的关键字,这是责任垃圾收集器在其作用域结束后释放对象内存。

所以我的问题是,

  1. 是上面的代码简单的处理,以腾出资源
  2. 按我的理解,明确的方式,我们的.NET框架下使用任何方法或类是托管代码,那么StreamReader也不属于托管代码。
  3. 我失去了对管理\非托管代码
+3

的''StreamReader''可能被使用在它的实现一些非托管资源的对象班,所以它将确保它们在使用 –

+1

包裹时处理。所以在您提供的示例中,这将是用于打开文件以供阅读的文件句柄。 – stuartd

+6

文件I/O是特定于操作系统的服务,在Windows中使用句柄方法时,句柄需要关闭。 –

回答

-5

我认为这更多的是一种防御性的编码风格,我不希望流读者对象被用作与此对象关联的文件有东西已经使用ReadtoEnd函数完全读取并正在被txt引用。

+0

这是不真实的。 '存在'用于确保保证(或至少尽可能接近它)并及时清理非托管资源。这不仅仅是一个范围界定机制。 – Servy

+0

操作系统API已完成读取文件的请求,此API在I/O完成时需要通知以释放相关资源。如果某件事实现了IDisposable,那么总是处置它。 –

1

为什么使用这个代码使用的关键字,而StreamReader的是 管理资源

虽然StreamReader的是一个管理对象可能保持在它里面的对象未在托管堆中分配。垃圾收集器无法识别其分配,因此无法清理它们。对于StreamReader的特殊情况,它会在内部创建一个FileStream(针对您的特定情况),它在内部创建并保存WIN32文件句柄。

_handle = Win32Native.SafeCreateFile(tempPath, fAccess, share, secAttrs, mode, flagsAndAttributes, IntPtr.Zero); 

(代码Reference

using仅仅是速记:

try 
{ 
    var streamReader = new StreamReader(path); 
    // code 
} 
finally 
{ 
    streamReader.Dispose(); 
} 

方法实施IDisposable需要执行Dispose他们有机会关闭文件句柄,套接字或任何这样的可能需要手动清洁的资源。

如果有人选择在课堂中持有StreamReader,那么该课程也应实施IDisposable,以便将Dispose正确传递到StreamReader

所以IDisposable可视为合同的,要么持有原生对象,或认为实现IDisposable