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最初に外部のデータベースを解放せずに、同じデータベースへの別の接続を確立していることを意味します。再帰呼び出しの数を取得すると、無料の接続がすぐに不足します。

一般に、データベースを処理するコードの一部で再帰呼び出しを使用することは、非常に悪い習慣と見なされます。

ここで本当にこの再帰が必要な場合でも、外部で実行する必要がありますusingx,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 に答える