1

我收到“超时已过期。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。” 错误,但找不到问题出在哪里。一点帮助,请。:)

public static void Update(string p, int c)
    {
        using (SqlConnection conn = new SqlConnection("ConnectionString"))
        {
            SqlCommand cmd = new SqlCommand();
            SqlDataReader myRdr;

            cmd.Connection = conn;
            cmd.CommandText = "SOME SQL QUERY @parameter";
            cmd.CommandType = CommandType.Text;
            cmd.Parameters.Add("@parameter", SqlDbType.NVarChar, 10).Value = p;

            conn.Open();
            myRdr = cmd.ExecuteReader();

            if (myRdr.HasRows)
            {
                while (myRdr.Read())
                {
                    //do something using myRdr data
                }
                myRdr.Close();
                cmd.Dispose();

                foreach (DataRow r in dt.Rows)
                {
                    SqlCommand cmd1 = new SqlCommand();

                    cmd1.Connection = conn;
                    cmd1.CommandText = "SOME SQL QUERY @parameter";
                    cmd1.CommandType = CommandType.Text;
                    cmd1.Parameters.Add("@parameter", SqlDbType.NVarChar, 10).Value = r["SomeData"];

                    myRdr = cmd1.ExecuteReader();
                    myRdr.Read();

                    //do something with myRdr data

                    myRdr.Close();
                    cmd1.Dispose();

                    int a = Convert.ToInt32(r["SomeData"]) - Convert.ToInt32(r["SomeData1"]);

                    if (a >= 0)
                    {
                        //do something
                    }
                    else
                    {
                        //do something else and runn the Update() again with some other parameters

                        Update(x, y); //I think here is some problem...
                                      //because when this condition is not met and program 
                                      //does not need to run Update() again, it goes OK and I get no error
                    }
                }
            }
            else
            {
                myRdr.Close();
                cmd.Dispose();
            }
        }
    }
4

2 回答 2

3

您应该考虑将您的呼叫转移Update(x,y)到外部using()块之外的某个地方。

从内部调用它using意味着您要建立与同一数据库的另一个连接,而无需先释放外部连接。如果您获得递归调用的数量,那么您将很快用完免费连接。

通常,在处理数据库的部分代码中使用递归调用被认为是一种非常糟糕的做法。

如果你真的需要这个递归,那么它仍然应该在 external 之外完成using。我建议将您的集合缓存x,y在某种集合中,并Update(x,y)通过在块外遍历此集合来发出调用using,如下所示:

public static void Update(string p, int c)
{
    // I'd suggest Dictionary, but don't know whether your strings are unique
    var recursionParameters = new List<KeyValuePair<string, int>>(); 

    using (SqlConnection conn = new SqlConnection("ConnectionString"))
    {
        ...
                    //do something else and runn the Update() again with some other parameters

                    //Update(x, y); Don't do it here! Instead:
                    recursionParameters.Add(new KeyValuePair<string, int>(x,y));
        ...
    }
    foreach (var kvp in recursionParameters
    {
        Update(kvp.Key, kvp.Value)
    }
}
于 2012-01-14T15:07:44.010 回答
1

发生异常时您Reader可能不会关闭。用 try finally 块包围它,所以当您遇到异常时,您的阅读器将关闭 finally 语句。

try
{  
    myRdr = cmd.ExecuteReader();
    // do some other stuff
}
catch(SqlException)
{
    // log the exception or deal with ex.

}
finally
{
    myRdr.Close(); // you can be sure it will be closed even on exception

}
于 2012-01-14T15:07:55.403 回答