[英]Running out of connections in pool
我有一个Web窗体应用程序,它将在GridView中显示记录列表,并且通过选中多个复选框,您可以批量删除记录。 代码本身很简单:
protected void btnDelete_Click(object sender, EventArgs e)
{
int i = 0;
try
{
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("ID");
if (cb != null && cb.Checked)
{
int profileID = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Value);
Profile profile = new Profile(profileID); //instantiate profile
profile.Delete(); //call delete method
i++;
}
}
if (i > 0)
{
//report success to UI
}
}
catch (Exception ex)
{
//report error to UI
}
}
在配置文件构造函数中,它通过打开连接,打开数据读取器然后设置对象的属性来水合对象。 我对代码中的using()
块一丝不苟,所以每个数据库连接看起来都像这样:
using (SQLHelper db = new SQLHelper())
{
db.AddParameterToSQLCommand("@ProfileID", SqlDbType.Int);
db.SetSQLCommandParameterValue("@ProfileID", id);
using (SqlDataReader dr = db.GetReaderByCmd("up_GetProfile"))
{
if (dr.Read())
{
_profileID = id;
if (!dr.IsDBNull(0))
ProfileName = dr.GetString(0);
//... and so on
return true;
}
else
{
return false;
}
}
}
数据读取器实现了iDisposible,我的助手类也实现了,析构函数如下所示:
public void Dispose()
{
try
{
//Clean Up Connection Object
if (mobj_SqlConnection != null)
{
if (mobj_SqlConnection.State != ConnectionState.Closed)
{
mobj_SqlConnection.Close();
}
mobj_SqlConnection.Dispose();
}
//Clean Up Command Object
if (mobj_SqlCommand != null)
{
mobj_SqlCommand.Dispose();
}
}
catch (Exception ex)
{
throw new Exception("Error disposing data class." + Environment.NewLine + ex.Message);
}
}
当我单步执行代码时,我看到连接总是一直正确打开和关闭,我的堆栈深度不超过五个或六个调用(我没有遇到任何递归问题),我已经确认所有数据访问代码都是正确包装在使用块,但我的连接没有释放回池中。 相反,我得到这个错误:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
这种情况发生在专用的应用程序池中,只有一个用户删除了10多个配置文件。 似乎我做的一切都正确,但是我对为什么没有将连接释放回池感到困惑。 最多只应有两个由执行线程打开的连接,当它们超出范围时,这两个连接都应该(并且必须执行)。
我显然做错了事,但我一生无法弄清楚是什么。
根据我的评论,我将转换为答案。
似乎您正在尝试在Command对象之前关闭Connection对象,并且由于Command对象引用了连接,因此它可能会使该连接保持活动状态。
尝试切换它们:
//Clean Up Command Object
if (mobj_SqlCommand != null)
{
mobj_SqlCommand.Dispose();
}
if (mobj_SqlConnection != null)
{
if (mobj_SqlConnection.State != ConnectionState.Closed)
{
mobj_SqlConnection.Close();
}
mobj_SqlConnection.Dispose();
}
如果我没记错的话,SqlHelper处理不会自动关闭连接。 您需要显式关闭它。
我们总是在try / final中包装SqlHelper的用法,并在finally中显式调用close。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.