【问题标题】:How to fix "Timeout period elapsed prior to obtaining a connection from the pool"如何修复“从池中获取连接之前已过超时时间”
【发布时间】:2020-02-01 05:27:57
【问题描述】:

在加载网站上的一个页面时,似乎经常出现以下错误。

“超时。在从池中获取连接之前已经过了超时时间。这可能是因为所有池中的连接都在使用中并且达到了最大池大小。”

根据我在四处搜索中发现的情况,似乎数据库连接没有正确关闭并因此泄漏。但我对 ASP.net 不太熟悉,因此非常感谢一些指导。

private void DisplayData()
    {
        SqlConnection objCon = new SqlConnection();
        objCon.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        objCon.Open();

        SqlCommand objCmd = new SqlCommand();
        objCmd.Connection = objCon;

        if (Request["Category"] == "some_cat")
        {
            objCmd.CommandText = "Select * From Community Where Category = N'some_cat' Order By Num Desc";
        }
        else if (Request["Category"] == "other_cat")
        {
            objCmd.CommandText = "Select * From Community Where Category = N'other_cat' Order By Num Desc";
        }
        else if (Request["Category"] == "Blog")
        {
            objCmd.CommandText = "Select * From Community Where Category = N'Blog' Order By Num Desc";
        }
        else if (Request["Category"] == "All")
        {
            objCmd.CommandText = "Select * From Community Where Category != N'Blog' Order By Num Desc";
        }


        objCmd.CommandType = CommandType.Text;

        SqlDataAdapter objDa = new SqlDataAdapter();
        objDa.SelectCommand = objCmd;

        DataSet objDs = new DataSet();

        objDa.Fill(objDs, "Community");

        this.ctlList.DataSource = objDs.Tables[0];
        this.ctlList.DataBind();

    objCon.Close();

    }

【问题讨论】:

  • 连接对象是一次性对象。未能处置它可能会导致此错误。了解如何使用 using statement(在所有 SqlConnection 实例上)
  • 旁注:您可以编写一个参数化查询来避免所有这些 if 逻辑。
  • @Steve 你能提供一个使用我发布的代码的例子吗?
  • 它只是 using(SqlConnection objCon = new SqlConnection()) { ....所有当前代码减去 objCon.Close().....}

标签: c# asp.net


【解决方案1】:

您的问题可能源于连接对象的丢失处置。一次性对象应disposed(IE 调用其 Dispose 方法)以释放对象中包含的所有非托管资源。 using 语句 将简化此操作,因为即使出现异常,它也会为包含在其起始块中的对象调用 Dispose 方法。

using 语句是编写 try/finally 块的简单方法

SqlConnection con = new SqlConnection();
try
{

}
finally
{
    con.Dispose(); // And this will also close the connection
}

所以你的代码可以改为:

private void DisplayData()
{
    using(SqlConnection objCon = new SqlConnection())
    using(SqlCommand objCmd = new SqlCommand())
    {
         objCon.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        objCon.Open();

        objCmd.Connection = objCon;
        objCmd.CommandText = "Select * From Community Where Category = @cat Order By Num Desc";
        objCmd.Parameters.Add("@cat", SqlDbType.NVarChar).Value = Request["Category"].ToString();

        if (Request["Category"] == "All")
        {
           objCmd.CommandText = "Select * From Community Where Category != @cat Order By Num";
           objCmd.Parameters[0].Value = "Blog"    
        }
        SqlDataAdapter objDa = new SqlDataAdapter();
        objDa.SelectCommand = objCmd;
        DataSet objDs = new DataSet();
        objDa.Fill(objDs, "Community");
        this.ctlList.DataSource = objDs.Tables[0];
        this.ctlList.DataBind();
}

当然,要消除连接池问题,您应该检查创建 SqlConnection 并实现 using 块的所有代码。

【讨论】:

  • 非常感谢您的详细解释和代码。
猜你喜欢
  • 2014-07-07
  • 2014-03-17
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多