'ExecuteReader需要一个打开且可用的连接.连接的当前状态为打开

本文关键字:连接 状态 一个 ExecuteReader | 更新日期: 2023-09-27 18:12:19

一个用c#编写的相当大的web应用程序不断抛出两个错误:

'ExecuteReader '需要一个打开的可用连接。连接的当前状态为打开。和' reader已关闭,试图调用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。为阅读器关闭连接。检查MARS是否使能。确保每次都创建一个新的连接对象。

我花了很长时间来寻找解决这个问题的方法,更不用说花了很长时间试图让它工作,我现在几乎要把头发拔出来了!

请帮忙!

EDIT -修复问题,见注释部分

'ExecuteReader需要一个打开且可用的连接.连接的当前状态为打开

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

您现在遇到多线程问题。

你有两个选择:

  • [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);
        }