‘ExecuteReader需要一个开放且可用的连接。 连接的当前状态是打开的’

用C#编写的一个相当大的Web应用程序不断抛出2个错误:

‘ExecuteReader需要一个开放且可用的连接。 连接的当前状态是打开的。 并且’读取器关闭时无效尝试调用读取。’

这些错误是偶然的 – 用于在95%的时间内加载精细的页面,但最近它们已成为地方病,它们一直在发生并且基本上削弱了应用程序的function。

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(); } } 

我在网上研究过这些错误,我看到了一些我试过无用的潜在解决方案:

将代码的各个部分放在using()块中。 为阅读器指定CommandBehaviour.CloseConnection。 检查MARS是否已启用。 确保每次都创建一个新的连接对象。

我花了很长时间寻找解决方案,更不用说长时间试图让它发挥作用,而我现在几乎要拔掉我的头发了!

请帮忙!

编辑 – 修正了问题,请参阅评论部分。

除了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); } 

在我看来, Database是一种类型,而不是一个实例。

您现在遇到multithreading问题。

你有2个选择:

  • [ThreadStatic]应用于包含Database.Open()创建的连接对象的字段

要么

  • Make Database.Open()返回连接对象的新实例,并在构造命令时使用它