好吧,它不会被处置,因为最终确定不是处置。
中有一个终结器System.ComponentModel.Component
,但在SQLConnection
的构造函数中被抑制了。如果您从具有终结器的东西继承,这是一个好主意,您知道 100% 确定您不需要,但否则是个坏主意。在这种情况下,这是个好主意。
但请记住,这SqlConnection
是对“真实”连接的包装。实际上,它很可能是一组变化的对象的包装,这些对象代表不同的连接状态。这是允许“真实”连接有效池化的机制的一部分,因为每次调用Open()
它都会从池中获取相关对象,并且每次调用时Close()
(无论是直接调用,Dispose()
还是通过离开一个范围using
) 它返回它。
现在,请记住,只有直接持有非托管资源或其他与 GC 无关的对象才需要最终确定。SqlConnection
持有一个对象,该对象可能(取决于 的状态SqlConnection
)是持有非托管资源的对象(或者实际上,更深于类的嵌套)。因此,没有必要对SqlConnection
to 本身进行最终确定。SqlConnection
考虑 open不再是 open的三种可能方式SqlConnection
:
Close()
叫做。这会立即返回到池的真实连接(如果没有池,则将其关闭)。
Dispose()
叫做。这调用Close()
具有相同的效果。
- 该对象被垃圾收集。
现在,在第三种情况下,对象持有对具有实际连接的对象的引用。它也是唯一这样做的对象。因此,该对象也将被垃圾收集。如果它有一个终结器(它可能有,尽管我不会假设没有更多聪明的技巧在进行),那么终结器将导致它被放入终结器队列中,并且最终会被终结。
如果SqlConnection
有一个终结器,唯一真正的效果是:
- 潜在的错误代码(在终结器代码中处理可终结的成员是令人担忧的,因为你不知道它们是否已经被终结)。
- 可能会减慢速度(无论如何,真正的连接都会被最终确定,充其量我们只是在减慢最终确定和 GC 的速度)。
- 无论如何,这里无事可做(真正的连接将在没有任何帮助的情况下完成)。
因此,将决赛选手放在比赛中SqlConnection
是没有胜利的失败。此外,您的真正联系应该有望最终确定。
这就是说,它仍然远非理想,并且仍然很可能泄漏连接。你能详细说明为什么你不能打电话Close()
或处置自己吗?管理连接的代码不能为您调用 close(对象应该在某个地方结束它的日子,并且应该在那里关闭)吗?
您是否需要让它保持活动状态才能允许IDataReader
从 an 提供的对象或对象完成?IDataReader
在这种情况下,您可以使用该CommandBehavior.CloseConnection
标志以便关闭(或处置)阅读器关闭连接吗?后一种情况是我记得的唯一一种不得不让连接离开作用域的情况。