暗战在池中的连接 [英] Running out of connections in pool

查看:124
本文介绍了暗战在池中的连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web窗体应用程序,将显示在GridView的记录列表,并通过检查多个复选框可以批量删除记录。 C本身的$ C $是直截了当的:

I have a web forms app that will display a list of records in a GridView and by checking multiple checkboxes you can mass delete the records. The code itself is straightforward:

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
    }
}

在轮廓的构造,它滋润打开了一个连接,打开一个DataReader,然后设置对象的属性的对象。我小心翼翼的使用()在我的code块,这样每一个数据库连接看起来大约是这样的:

In the profile constructor, it hydrates the object by opening up a connection, opening a datareader and then setting the properties of the object. I am meticulous about using() blocks in my code so every db connection looks about like this:

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;
        }
    }
}

一个DataReader实现iDisposible一样,我的辅助类和析构函数如下:

A datareader implements iDisposible, as does my helper class, and the destructor looks like this:

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

当我通过我的code步骤我看到连接总是被打开和关闭正确,我的筹码是不会超过五六个电话深(我没有运行到任何递归问题),我已经证实,我的所有数据访问code正确地裹在使用块但我的连接不会被释放回池中。相反,我得到这个错误:

When I step through my code I see that connections are always being opened and closed correctly, my stack is never more than five or six calls deep (I'm not running into any recursion problems) I have confirmed that all my data access code is correctly wrapped in using blocks yet my connections aren't being released back to the pool. Instead I get this error:

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+型材专用的应用程序池。 它的似乎的像我在做正确的一切,但我很茫然,为什么连接不被释放回池中。在的,应该永远只能是两个连接的执行线程开放,这两者应该(和做!),当他们走出去的范围处置。

This happens in a dedicated app pool with a single user effecting a delete on 10+ profiles. It seems like I'm doing everything correctly but I am at a loss as to why connections are not being released back to the pool. At most there should only ever be two connections open by the executing thread, both of which should (and do!) dispose when they go out of scope.

我清楚地做错事,但不能为我的生活找不出什么。

I'm clearly doing something wrong but can't for the life of me figure out what.

推荐答案

这是我的意见,我将转换为一个答案。

From my comment, I'll convert to an answer.

您好像正在试图之前Command对象关闭连接对象,因为Command对象引用的连接,它可能会保持连接活着。

It looks like you are trying to close your Connection objects before the Command objects, and since the Command objects reference a connection, it might be keeping the connection alive.

试着围绕转换他们:

//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();
}

这篇关于暗战在池中的连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆