sur*_*lit 6 c# t-sql exception sqldatareader
用C#编写的一个相当大的Web应用程序不断抛出2个错误:
'ExecuteReader需要一个开放且可用的连接.连接的当前状态是打开的.并且'读取器关闭时无效尝试调用读取.'
这些错误是偶然的 - 用于在95%的时间内加载精细的页面,但最近它们变得流行,它们一直在发生并且基本上削弱了应用程序的功能.
Web应用程序高度依赖于MS SQL数据库,并且错误似乎不仅限于一个页面,而是几乎所有连接到数据库的页面.
查询按如下方式执行:
Database.Open(); // Custom class that has our connection string hard coded.
string query = "SELECT * FROM table"; // (dummy query)
SqlCommand command = new SqlCommand(query, Database.Conn);
SqlDataReader reader = null;
try {
reader = command.ExecuteReader(CommandBehaviour.CloseConnection);
if (reader.HasRows) {
while (reader.Read()) {
// Do something with the data.
}
}
reader.Close();
}
catch (Exception e) {
throw new Exception(e.Message);
}
finally {
if (reader != null) {
reader.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
我在网上研究过这些错误,并且我已经看到了一些我试过无用的潜在解决方案:
将代码的各个部分放在using()块中.为阅读器指定CommandBehaviour.CloseConnection.检查MARS是否已启用.确保每次都创建新的连接对象.
我花了很长时间寻找解决方案,更不用说长时间试图让它起作用了,而我现在几乎要把头发拉出来了!
请帮忙!
编辑 - 修复了问题,请参阅注释部分.
在我看来,这Database
是一种类型,而不是一个实例.
您现在遇到多线程问题.
你有2个选择:
[ThreadStatic]
应用于包含由其创建的连接对象的字段Database.Open()
要么
Database.Open()
返回的连接对象的新实例,并使用构建命令时除了leppie的答案之外,您还应该Dispose()
使用任何IDisposable
类型:
try
{
Database.Open(); // Custom class that has our connection string hard coded.
string query = "SELECT * FROM table"; // (dummy query)
using (SqlCommand command = new SqlCommand(query, Database.Conn))
using (SqlDataReader reader = command.ExecuteReader(CommandBehaviour.CloseConnection))
{
if (reader.HasRows)
{
while (reader.Read())
{
// Do something with the data.
}
}
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
Run Code Online (Sandbox Code Playgroud)