【发布时间】:2011-07-26 23:09:42
【问题描述】:
有没有需要如下结构的情况?
using (Something something = new Something())
{
try
{
}
finally
{
something.SomeCleanup();
}
}
或者,是否应该所有在隐式something.Dispose()调用中执行清理任务?
这是有问题的代码:
public static DataTable GetDataTable(string cmdText, IEnumerable<Parameter> parameters)
{
// Create an empty memory table.
DataTable dataTable = new DataTable();
// Open a connection to the database.
using (SqlConnection connection = new SqlConnection(ConfigurationTool.ConnectionString))
{
connection.Open();
// Specify the stored procedure call and its parameters.
using (SqlCommand command = new SqlCommand(cmdText, connection))
{
command.CommandType = CommandType.StoredProcedure;
SqlParameterCollection parameterCollection = command.Parameters;
foreach (Parameter parameter in parameters)
parameterCollection.Add(parameter.SqlParameter);
try
{
// Execute the stored procedure and retrieve the results in the table.
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
try
{
dataAdapter.Fill(dataTable);
}
catch
{
dataTable.Dispose();
dataTable = null;
}
}
finally
{
//parameterCollection.Clear();
}
}
}
return dataTable;
}
注意:我已经定义了Parameter 类,所以这个函数的用户不必直接处理SqlParameters 的创建。 Parameter 类的SqlParameter 属性可用于检索SqlParameter。
在某些时候,我的程序执行以下操作(无法发布代码,因为它涉及很多类;基本上,我有一个创建大量对象的迷你框架):
- 创建一个
Parameters 的数组。 -
GetDataTable('sp_one', parameters)。 -
GetDataTable('sp_two', parameters)。
【问题讨论】:
-
您创建了 Something 类吗?如果是这样,为什么不把所有的清理操作都放在 Dispose 方法中?
-
@mbeckish:我没有创建
Something类。实际上,我的Something类是微软自己的SqlConnection和SqlParameter。常识说微软程序员足够聪明,可以在Dispose方法中关闭打开的数据库连接(当然,这并不意味着他们也不应该提供Close方法),但文档什么也没说。我真的很怀念使用 C++ 和访问 STL 的源代码。 -
我很确定
SqlConnection.Dispose的作用与Close的作用相同(除了能够在Close之后重新打开,而不是Dispose)。如果您的连接实际上没有关闭,则可能是由于连接池。顺便说一句,你实际上可以访问源代码,它已经发布,你也可以使用反射器reflector.red-gate.com/download.aspx?TreatAsUpdate=1 -
@František Žiačik:我不知道
SqlConnection.Dispose实际上关闭了连接,所以这是我无知的错。但我很确定当我第二次尝试将 SqlParameter 添加到 SqlParameterCollection 时出现“另一个 SqlParameterCollection 包含 SqlParameter”错误,即使第一个SqlParameterCollection属于已经处置的SqlCommand。 -
你为什么不直接创建新的SqlParameter?这只是一个设计决策问题,其中有人决定只能将 SqlParameter 添加到单个 SqlParameterCollection(我不知道为什么)并且与 Dispose 模式无关。您无需担心内存问题,这就是垃圾收集器可以提供帮助的地方。
标签: .net using try-finally