垃圾收集与IDisposable

Fra*_*ank 4 .net c# collections resources idisposable

我正和一个人谈论使用()语句.

他说如果我们不对像StreamWriter这样的东西使用using()语句,如果发生任何异常,资源将永远不会被收集.

我确实理解使用using()语句,但我不同意永远不会收集资源.我认为using()语句最后会调用dispose()方法,这可以使集合更快.但是,即使我们不使用using(),我们也不会调用dispose(),但仍可以通过gabage收集来收集资源,尽管可能需要更长的时间.

你同意谁?

PS.我知道你们都在说什么.使用using()语句很重要.我只是想知道如果我们不这样做,资源肯定永远不会被收集?

Eri*_*ert 10

让我们清楚这一点.假设有问题的资源是文件句柄.垃圾收集器对文件句柄或如何释放它一无所知.文件句柄只是一个整数.

如果持有文件句柄的StreamWriter被垃圾收集,那么垃圾收集器会将该对象放入终结队列.当终结队列运行时,它将调用对象的终结器,就是释放文件句柄的原因.

这一切都清楚了吗?垃圾收集器不释放资源; 垃圾收集器知道的唯一资源是内存中的对象.在释放对象之前,它已完成,因此对象本身知道如何释放资源.


Håv*_*d S 1

Dispose()当你使用完一个对象后,你应该总是调用IDisposable。声明using是确保您遵守此规则的一个很好的工具。

目的IDisposable是允许类处理分配的非托管资源,这些资源不会被垃圾收集自动清理。

如果您使用一个IDisposable对象而不在完成后调用Dispose(),那么您将面临永远无法正确处置该资源的风险,即使在它已被垃圾收集之后也是如此。

这就是该声明存在的原因using;它提供了使用IDisposable对象的便捷语法,并定义了这些对象的可用范围。

另请注意,垃圾收集器从不调用Dispose()自身,但另请注意,建议遵循MSDN 上记录的 Finalize/Dispose 模式。如果对象遵循 Finalize/Dispose 模式,Dispose()则当 GC 调用终结器时将调用该对象。

  • 不,GC 不会调用“Dispose()”。建议实现者遵循 Finalize/Dispose 模式,其中终结器调用“Dispose(false)”。但不能保证该实现确实做到了这一点。 (2认同)