当前位置:  开发笔记 > 前端 > 正文

关闭和处理 - 要打电话?

如何解决《关闭和处理-要打电话?》经验,为你挑选了5个好方法。

读完线程后SqlCommand.Dispose足够吗?和关闭和处置WCF服务,我琢磨类,如SqlConnection的或几类从Stream类继承它的问题,如果我收处置,而不是关闭的一个?



1> aku..:

我想澄清一下这种情况.

根据Microsoft指南,Close在合适的地方提供方法是一种很好的做法.这是框架设计指南的引用

考虑提供方法Close(),除了Dispose(),如果收盘价在该地区的标准术语.这样做时,重要的是要使Close实现与Dispose... 相同.

在大多数情况下Close,Dispose方法是等效的.的主要区别之间CloseDispose在的情况下SqlConnectionObject为:

一个应用程序可以调用Close多次.没有异常生成.

如果调用Dispose方法 SqlConnection对象状态将被重置.如果您尝试在已处置SqlConnection 对象上调用任何方法,则会收到异常.

那说:

如果您使用连接对象一次,请使用Dispose.

如果必须重用连接对象,请使用Close方法.


@Chris,Close()的文档说"它然后释放连接池的连接,或者如果禁用连接池则关闭连接".所以Close()应该足以防止连接池溢出.
.Dispose()是否还将连接释放回池中?
@oscilatingcretin,他们在这方面的工作方式相同.

2> Brannon..:

像往常一样答案是:这取决于.不同的类IDisposable以不同的方式实现,由您来完成必要的研究.

目前SqlClient,建议的做法是执行以下操作:

using (SqlConnection conn = /* Create new instance using your favorite method */)
{
    conn.Open();
    using (SqlCommand command = /* Create new instance using your favorite method */)
    {
        // Do work
    }
    conn.Close(); // Optional
}

应该在连接上调用Dispose(或Close*)!难道不是等待垃圾回收器来清理你的连接,这将占用连接池中,直到下一个GC周期(至少).如果你打电话Dispose,没有必要打电话Close,因为这个using结构让它很容易Dispose正确处理,所以没有理由打电话Close.

连接会自动进行池化,并且呼叫Dispose/ Close连接不会物理关闭连接(在正常情况下).不要尝试实现自己的池. SqlClient在从池中检索连接时对连接执行清理(如恢复数据库上下文和连接选项).

*如果您正在呼叫Close,请确保以异常安全的方式(即在捕获或最终阻止)中执行此操作.


我不会说:`conn.Close(); //可选`它不是可选的.这是多余的,没有必要.您正在处理该对象两次,这将被一些代码分析工具标记为警告.

3> Tyler..:

你需要调用Dispose()!

Dispose()供开发人员调用,垃圾收集器调用Finalize().如果你没有在你的对象上调用Dispose(),那么他们使用的任何非托管资源都不会被丢弃,直到垃圾收集器出现并调用它们(并且知道何时会发生).

此方案称为非确定性终结,是.net开发人员的常见陷阱.如果您正在使用实现IDisposable的对象,请在它们上调用Dispose()!

http://www.ondotnet.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html?page=last

虽然可能有许多实例(比如在SqlConnection上),你在某个对象上调用Disponse(),它只是在它的连接上调用Close()或关闭文件句柄,但几乎总是调用Dispose()!除非您打算在不久的将来重复使用该对象.


这个评论完全错误.垃圾收集器永远不会调用`Dispose`.
推论:你*应该*调用`Dispose()`*if*你没有使用`using()`和一个实现`IDisposable`的类.如果被调用的类实现了IDisposable并且你已经在`using()`中将它的用法包装在页面上,那么你可以使用`Dispose()`(双关语,所以拍我).但是,对于明确使用`Open()`,AFAIK的任何东西,建议使用`Close()`.

4> Curt Hagenlo..:

因为SqlConnection,从连接本身的角度来看,它们是等价的.根据Reflector,Dispose()调用Close()以及执行一些额外的内存释放操作 - 主要是通过将成员设置为null.

对于Stream,它们实际上是等价的. Stream.Dispose()只需调用Close().



5> André Chalel..:

这个快速的建议成了一个很长的答案.抱歉.

正如泰勒在他的回答中指出的那样,调用Dispose()是一种很棒的编程习惯.这是因为这种方法应该"集合"所需的所有资源释放,因此没有不需要的开放资源.例如,如果你在文件中写了一些文本,并且无法关闭文件(释放资源),那么它将保持打开状态,并且没有其他人能够写入它,直到GC到来并做你应该拥有的完成.

现在,在某些情况下,将会有更新特定于您正在处理的类的"最终化"方法,例如StreamWriter.Close(),覆盖哪些方法TextWriter.Close().实际上它们通常更适合这种情况:Close()例如,StreamWriter Dispose()在对象进入之前刷新流和底层编码器!凉!

但是,浏览MSDN你会发现即使微软有时也被大量的关闭器和处理器搞糊涂了.例如,在这个网页中,在一些示例Close()中,在隐式之前调用Dispose()(如果您不理解为什么它是隐式的,请参阅using语句),特别是在一个例子中他们不打扰.那为什么会这样?我也很困惑.

我想的原因(并且,我强调,这是原始研究,如果我错了,我肯定可能会失去声誉)是Close()可能会失败,在保持资源开放的同时产生异常,同时Dispose()肯定会释放它们.这就是为什么一个人Dispose()应该始终保护一个Close()电话(对不起双关语).

MyResource r = new MyResource();

try {
  r.Write(new Whatever());

  r.Close()
finally {
  r.Dispose();
}

是的,我想微软在这个例子上滑倒了.也许该时间戳永远不会被刷新到文件中.

我明天要修复旧代码.

编辑:对不起布兰农,我不能评论你的答案,但你确定打电话Close()给一个finally街区是个好主意吗?我想这个例外可能会破坏块的其余部分,这可能包含重要的清理代码.

回答Brannon的:好的,只是不要忘记在Close()真正需要时调用(例如在处理流时 - 对.NET中的SQL连接不太了解).

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有