1

已经有一个与此命令关联的打开的 DataReader,必须先关闭它。

当同一个人在不同系统上同时打开同一页面时,我面临这个问题。我对此进行了很多搜索,但没有找到成功的解决方案。

我累了:

  1. MultipleActiveResultSets = true在连接字符串中
  2. 增加连接等待时间
  3. 已验证所有连接已关闭

仅在创建上述条件时才会出现此问题。请让我知道真正有效的解决方案

这是我正在使用的连接功能

public DataSet SelectDs(string str)
{
    DataSet ds = new DataSet();

    if (con.State == ConnectionState.Closed)
    {
        con.ConnectionString = ConStr;
        con.Open();
    }

    cmd.CommandText = str;
    cmd.Connection = con;
    cmd.CommandTimeout = 12000;
    adpt.SelectCommand = cmd;
    adpt.Fill(ds);

    con.Close();
    return ds;
}
4

4 回答 4

2

以这种方式使用全局连接对象是一种致命的罪过。它在 WinForms 应用程序中很糟糕(非常糟糕),但在 ASP.NET 中是致命的。(正如你所发现的)

一次性对象(以及像连接这样昂贵的对象)的使用模式是

CREATE, OPEN, USE, CLOSE, DESTROY

连接池机制的存在使这种模式的使用更容易。
相反,您尝试与之抗衡并承担后果。

您的代码应重写为

public DataSet SelectDs(string str)
{
    DataSet ds = new DataSet();

    using(SqlConnection con = new SqlConnection(constring))  // CREATE
    using(SqlCommand cmd = new SqlCommand(str, con))         // CREATE
    {
        con.Open();    // OPEN
        cmd.CommandTimeout = 12000;
        using(SqlAdapter adpt = new SqlAdapter(cmd))   // USE
             adpt.Fill(ds);

        return ds;
    }  // CLOSE & DESTROY 
}
于 2013-06-13T08:53:39.820 回答
1

如何在 Using 语句中放入类似

    using(SqlConnection connection = new SqlConnection("connection string"))
{

connection.Open();

using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        if (reader != null)
        {
            while (reader.Read())
            {
                //do something
            }
        }
    } // reader closed and disposed up here

   } // command disposed here

 } //connection closed and disposed here
于 2013-06-13T07:55:47.367 回答
0

我认为您还应该在返回数据集之前处理您的命令对象。

在 con.close() 之后尝试 cmd.Dispose()

于 2013-06-13T09:51:52.543 回答
0

在 finally 子句中使用这个

if (readerObj.IsClosed == false)
{
  readerObj.Close();
}
于 2013-06-13T08:00:34.877 回答