如何在ADO上调用Dispose.网络对象
本文关键字:Dispose 网络 对象 调用 ADO | 更新日期: 2023-09-27 17:50:14
实现IDbConnection
、IDbCommand
和IDataReader
的数据库访问类都实现了IDisposable
,但显然Command和Reader依赖于Connection。我的问题是,我是否必须单独处理这些对象,或者处理连接对象也会处理其他对象?
也就是说,我是否可以这样做并保证我不会有任何未被释放的非托管资源的风险:
using (IDbConnection conn = GetConnection())
{
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = " ..... ";
IDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
}
}
或者我必须这样做:
using (IDbConnection conn = GetConnection())
{
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = " ..... ";
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
}
}
}
}
最好的策略是使用所有ADO。. NET对象使用块-句号。
对各种ADO的一点反射。. NET对象显示,如果没有关闭/处置,东西或多或少会掉在地板上。它的影响很大程度上取决于你使用的是哪个提供程序——如果你使用的是下面带有非托管句柄的东西(ODBC、OleDb等),你可能会泄漏内存,因为我没有看到任何终结器的方式。如果它是一个全托管的提供程序(例如SqlClient),它最终会被清理,但是取决于您持有的对象,您最终可能会在DB服务器上保持使用的资源比您想要的时间长得多。
您应该单独处理它们,或者您也可以使用这里提供的解决方案。
分别处理。Reader和Command对象完全有可能在它们的dispose例程中做更多的事情,而不仅仅是销毁连接(无论是现在还是将来的ADO.NET版本)。因此,为了(a)明确和(b)安全,您应该单独处理它们。
它们实现IDisposable的事实表明,当您完成对象时,您应该始终运行Dispose例程,因此最好不要尝试重新猜测接口,它不会给您带来任何好处,并且您可能最终会泄漏内存和句柄。
当嵌套using
语句时,你可以做一些事情来使你的代码看起来更干净。例如:(using SqlConnection conn = new SqlConnection())
(using SqlCommand comm = new SqlCommand())
{
//Do stuff
}
这看起来比嵌套大括号更整洁(在我看来)
您应该单独处理它们。即使处理IDbConnection会处理隐藏的所有内容(我不知道它是否真的会这样做,我也不关心,原因如下),您也应该使用将来时态进行编程。明天有人会编辑该代码并在同一连接上发出新命令,然后它会想知道为什么他得到连接仍在使用的错误(因为IDataReader没有被处置)。
using语句的主要优点是资源释放管理。通常,. net框架垃圾收集器控制资源的分配和释放。使用using语句,我们可以控制它。因此using语句实现了一个包含公共Dispose()方法的idispossible接口。
也可以手动调用Dispose()方法从内存中释放资源或对象。
希望这对你有帮助。