C# 了解,;重现ExecuteReader InvalidOperationException(“连接的当前状态为打开”)
我收到一位用户的报告,称他们在使用我的应用程序时遇到此异常:C# 了解,;重现ExecuteReader InvalidOperationException(“连接的当前状态为打开”),c#,sql-server,executereader,C#,Sql Server,Executereader,我收到一位用户的报告,称他们在使用我的应用程序时遇到此异常: ExecuteReader requires an open and available Connection. The connection's current state is open. | System.InvalidOperationException | at System.Data.SqlClient.SqlConnection
ExecuteReader requires an open and available Connection. The connection's current state is open.
| System.InvalidOperationException
| at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method)
| at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
| at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
| at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
| at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
| at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
| at System.Data.SqlClient.SqlCommand.ExecuteReader()
| at MyProject.Database.GetData(DataType data, SqlConnection& _conn)
然而,我似乎无法重现这个异常,事实上我甚至不知道它是什么意思:即,如果连接的当前状态是打开的,那么问题出在哪里?为什么会有例外
我尝试过单步执行代码,连接状态为打开,但它只是正确读取数据。事实上,微软文档似乎暗示,如果连接关闭,就会发生这种情况,但正如您从异常消息中看到的,它是打开的
以下是相关代码:
private int GetData(DataType data, ref SqlConnection _conn)
{
string sqlStr = string.Format("select top 1 * from dbo.DataTable where [Id] = N'{0}'", data.Id);
using (SqlCommand cmd = new SqlCommand(sqlStr, _conn))
{
SqlDataReader rs = null;
try
{
if (_trans != null) cmd.Transaction = _trans;
rs = cmd.ExecuteReader();
if (rs == null)
return DB_ERROR;
int attI = rs.GetOrdinal("FileData");
int fileNameI = rs.GetOrdinal("FileName");
while (rs.Read())
{
dataFile.FileData = (byte[]) rs.GetValue(attI);
dataFile.FileName = DBCommon.ColStr(rs, fileNameI);
}
rs.Close();
rs = null;
return DB_OK;
}
catch (Exception e)
{
LogException(e);
return DB_ERROR;
}
finally
{
if (rs != null)
rs.Close();
rs = null;
}
}
}
在调试时,我检查_conn.State
属性,检查它是否是打开的
,然后逐步执行rs=cmd.ExecuteReader()代码>行,但它处理得很好
应该注意的是,这是一个非常大的应用程序,有许多表,每个表都有自己的方法,类似于上面的一个,都引用了\u conn
对象。重组它是不可行的
任何其他问题都有关于如何预防它的答案,但我正试图重现它,并理解它发生的确切原因 获取传入的SqlConnection
而不是自己创建连接的方法总是可疑的。有没有可能从多个线程获得一个连接对象?ADO.NET操作上很少有线程安全的操作。此代码还有其他警告信号(如不使用使用
读卡器、捕获异常
、使用错误返回值和模糊的“帮助器方法使事情变得更简单”),但让我们暂时忽略这些。更令人担忧的是,参数被声明为ref
。此方法不会替换该值,但是否有其他方法可以替换该值?这使得跟踪实际使用的连接更加危险。如果ref
-ness没有在任何地方使用,这可能只是作者不理解引用类型如何工作的一个怪癖,或者是某个习惯于经典VB的人(其中传递值/引用的区别要明确得多)。