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

时间:2011-10-24 15:32:46

标签: c# tsql exception sqldatareader

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

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

这些错误是零星的 - 大约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();
    }
}

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

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

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

请帮忙!

编辑 - 解决了问题,请参阅评论部分。

2 个答案:

答案 0 :(得分:6)

我认为Database是一种类型,而不是一个实例。

您现在遇到多线程问题。

您有两个选择:

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

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

答案 1 :(得分:4)

除了leppieanswer之外,您还应该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);
        }