2010-05-04 68 views
12

我是C#和.NET的新手,并且一直在阅读它。.NET中的版本资源#

我需要知道为什么以及何时需要释放资源?垃圾收集器不会处理所有事情吗?我什么时候需要实现IDisposable,它与C++中的析构函数有什么不同?

此外,如果我的程序比较小,即屏幕保护程序,我是否需要关心释放资源?

谢谢。

+0

试试这个链接 - http://ondotnet.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html – Gishu 2010-05-04 09:23:27

+1

这个问题也是相关的:http://stackoverflow.com/questions/317184/c-using -key-when-and-when-not-to-use-it – 2010-05-04 09:27:00

回答

2

基本上,您需要担心将资源释放给非托管代码 - .NET框架之外的任何东西。例如,数据库连接或OS上的文件。

垃圾回收器处理托管代码 - .NET框架中的代码。

即使一个小应用程序可能需要释放非托管资源,例如它可能会写入本地文本文件。当你完成资源的配置时,你需要确保调用该对象的Dispose方法。所述using语句简化了的语法:

using (TextWriter w = File.CreateText("test.txt")) 
{ 
    w.WriteLine("Test Line 1"); 
} 

所述的TextWriter对象,以便一旦使用块结束Dispose方法被调用,所述对象可以是垃圾收集实现IDisposable接口。收集的实际时间不能得到保证。

如果你创建了你自己需要被正确处置的类,你将需要自己实现IDisposable接口和Dispose模式。在一个简单的应用程序,你可能不需要这样做,如果你这样做this是一个很好的资源。

+0

好的解释。 – Ram 2010-05-05 14:45:31

1

您不需要释放托管对象(如字符串或数组)中的内存 - 由垃圾回收器处理。

完成使用后,您应该清理操作系统资源和一些非托管对象。如果你打开一个文件,你应该始终记住在完成使用后关闭该文件。如果您以独占方式打开文件并忘记关闭,下次您尝试打开该文件时,它可能仍会被锁定。如果某些东西实现了IDisposable,那么您一定要考虑是否需要正确关闭它。该文档通常会告诉你方法的作用以及应该何时调用。

如果忘了,垃圾回收器最终会运行终结器,它应该正确地清理对象并释放非托管资源,但是在对象符合垃圾回收的条件之后,它不会立即发生,事实上它可能会根本不运行。

此外,了解using声明是有用的。

14

垃圾收集器只知道内存。对于内存来说这很好,因为只要你有足够的内存,内存的一点就像其他任何内存一样好。 (这是所有的模缓存一致性等)

现在将它与文件句柄进行比较。操作系统可以有足够的空间来分配更多的文件句柄 - 但是如果您已经为特定文件开放了句柄,则其他人将无法打开特定文件进行编写。当你完成一个句柄时(通常通过关闭相关流),你应该告诉系统,一旦你完成了,并且以一种即使抛出异常时关闭它的方式来完成。这通常是通过using声明完成的,这个声明就像try/finally在finally块中调用Dispose一样。例如,当C++析构函数具有确定性时,它们会自动调用,例如,当相关变量超出范围时,会自动调用这些函数。C++中的析构函数是很有,与.NET终结符不同。终止器由垃圾收集器在某个点处运行,之后对象不再被任何“活动”对象引用,但时序不可预知。 (在某些罕见的情况下,可能从未发生。)

您应该实现IDisposable自己,如果你有任何的清理应确定性地完成 - 通常是这样的话,如果你的实例变量工具之一IDisposable。现在很少需要自己实现终结器 - 如果在操作系统句柄上持有直接(通常采用IntPtr的形式),通常只需要一个; SafeHandle使所有这一切变得更加容易,并让您免于自己编写终结器。

2

资源有两种 - 托管和非托管。如果您允许,被管理资源将被垃圾收集器清理 - 也就是说,如果您释放对该对象的任何引用。但是,垃圾收集不知道如何释放托管对象保存的非托管资源 - 例如文件句柄和其他操作系统资源。

当您想要立即发布托管资源(如数据库连接)时,IDisposable是最佳实践,当您需要释放非托管资源时,IDisposable至关重要。典型的模式:

public void Dispose() 
protected void Dispose(bool disposing) 

让您确保托管资源是否由Dispose方法或对象定稿公布。

0

垃圾回收器释放MEMORY并清除最新的处置 - elemetns它将被删除。但是:只有当它有内存压力时,它才会这样做。

这是严重的白痴,我可能希望明确释放他们的信息白痴。例如,保存到文件应该是:打开文件,写出数据并关闭文件,以便用户可以将文件复制掉,而无需等待GC出现并释放内存对于文件对象,这可能不会发生几个小时。

0

您只需要担心宝贵的资源。编程时创建的大多数对象都不适合此类别。正如你所说,垃圾收集器将照顾这些。

你需要注意的是实现IDisposable的对象,这表明它拥有的资源是宝贵的,并且不应该等待终结器线程被清理。唯一需要实现IDisposable的时间是拥有以下对象的类:实现IDisposable的对象(如文件流),或b)非托管资源。