我有一个愚蠢的问题,但我想在这里听到社区。 p>
所以这是我的代码:
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
return true;
}
我的问题,是否与以下不同:
(FtpWebResponse)request.GetResponse();
return true;
哪一个更好? GC中哪一个和为什么?
答案 0 :(得分:11)
第一个更好,但不是GC。 WebResponse
实现IDisposable
,因为它有需要释放的资源,例如网络连接,内存流等。IDisposable
已经到位,因为作为消费者,您知道何时完成使用该对象,您可以调用Dispose
通知您已完成的课程,并且可以自行清理。
using
模式实际上只是调用了Dispose
。例如。你的第一个例子实际编译为:
FtpWebResponse response = (FtpWebResponse)request.GetResponse()
try
{
}
finally
{
((IDisposable)response).Dispose();
}
return true;
这与垃圾收集器是分开的。一个类也可以清理终结器中的资源,它可以从GC中调用,但是你不应该依赖它来实现这两个原因:
答案 1 :(得分:7)
答案 2 :(得分:4)
我感谢您对此回复不感兴趣。但是,响应对象已创建,初始化并返回到您的代码,无论您是否需要它。如果你不处理它,那么它会消耗资源,直到GC最终完成它来完成它。
答案 3 :(得分:2)
我同意其他人的说法,但如果你对using()语法有这样的仇恨,你可以这样做:
((IDisposable)request.GetResponse()).Dispose();
return true;
答案 4 :(得分:1)
GC并不关心除内存以外的任何内容,因此如果你有足够的内存并且没有消耗太多内存,那么它可能需要很长时间才能运行GC。在整个过程中,非托管资源(例如网络连接,文件句柄,数据库连接,图形处理等)仍然被等待GC的对象所束缚。这可能会导致您耗尽这些资源,并且GC将无视,因为它不会监视非托管资源。
因此,如果您将代码放在循环中并继续调用它,而不调用Dispose,您可能会发现它很快就会降低性能(争夺稀缺资源的进程)或者由于缺少非托管资源而导致异常。它取决于它的调用方式以及如何创建其他相关对象。您可以在完成实例后立即调用Dispose,而不是分析每种情况。
确实最终Dispose将被GC调用一个超出范围/不再被引用的对象,但这是不确定的。由于存在不确定性,您可以看到在测试与生产时资源免费获取的时间不同的结果,并导致在资源耗尽时无法分配资源的随机异常。如果您可以选择应用程序的一致确定性行为和不确定性,那么您可能需要确定性,除非您尝试混淆测试人员。