2017-02-03 13 views
1

エラーメッセージが表示されます。 タイムアウトが切れています。プールから接続を取得する前にタイムアウト期間が経過しています。これは、プールされたすべての接続が使用中で、プールの最大サイズに達したために発生した可能性があります。- SQLコマンドのループで最大接続プールエラーを回避する方法

マイコード:

clsDBConn dbConn = new clsDBConn(); 
SqlDataCommand CMD; 

private void Recompute() 
{ 
    CMD = new SqlCommand("SELECT * FROM tblEmployee", dbConn.connection); 
    SqlDataReader EmplReader = CMD.ExecuteReader(); 
    while (EmplReader.Read()) 
    { 
     while(DateFrom >= DateTo) 
     { 
     //Some Reader 
     //Lots of SQL Command ExecuteNonQuery(); 
     } 
    } 
} 

私は、このエラーに関するいくつかのソリューションをお読みください。彼らは私が接続を開いて閉じるべきだと言います。 しかし、問題は、接続が閉じている場合、私はsqlcommandsで連結する必要があるリーダーの値にアクセスできません。

は、私が50プラス従業員ルーピングしていますし、各従業員は、時間の記録(Lates、OT、Undertimesなど)

私は何をすべきを計算しますか?

+0

エラーコマンドのタイムアウトはありますか? 私はあなたの従業員をメモリにロードすることをお勧めします。次に、処理するために各従業員のためのループを行います。 – ngeksyo

+1

'using'ステートメントで' IDisposable'を実装している 'SqlClient'オブジェクトの使用をラップします。 (実際には、そのアドバイスはSQLのものだけでなく、ほとんどの 'IDisposable'に適用されます) –

+1

リソースを破棄する必要があります。 – jjj

答えて

1

usingキーワードを使用して接続を配置してみて、あなたもまた、あなたのclsDBConnがIDisposableをインターフェイスを実装し、廃棄する(定義する必要がありますCommandTimeout

private void Recompute() 
{ 
    using(clsDBConn dbConn = new clsDBConn()) 
    { 
     SqlDataCommand CMD = new SqlCommand("SELECT * FROM tblEmployee", dbConn.connection); 
     CMD.CommandTimeout = 120; 
     using(SqlDataReader EmplReader = CMD.ExecuteReader()) 
     { 
      while (EmplReader.Read()) 
      { 
       while(DateFrom >= DateTo) 
       { 
        //Some Reader 
        //Lots of SQL Command ExecuteNonQuery(); 
       } 
      } 
     } 

    } 
} 

を追加することにより、およそタイムアウトを長くしようとすることができます)方法、

public class clsDBConn : IDisposable 
    { 
     private bool disposedValue = false; 

     .... 
     .... 
     .... 

     protected virtual void Dispose(bool disposing) 
     { 
      if (!disposedValue) 
      { 
       if (disposing) 
       { 
        // TODO: dispose managed state (managed objects). 
       } 

       disposedValue = true; 
      } 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 
    } 

二番目のオプション:あなたは(私が使用することを好むが、まだ動作していない)別のオプションを持っているあなたのclsDBConnは(.Closeを持っている場合)

private void Recompute() 
{ 
    clsDBConn dbConn = new clsDBConn(); 
    SqlDataCommand CMD = new SqlCommand("SELECT * FROM tblEmployee", dbConn.connection); 
    CMD.CommandTimeout = 120; 
    using(SqlDataReader EmplReader = CMD.ExecuteReader()) 
    { 
     while (EmplReader.Read()) 
     { 
      while(DateFrom >= DateTo) 
      { 
       //Some Reader 
       //Lots of SQL Command ExecuteNonQuery(); 
      } 
     } 
    } 

    dbConn.Close(); 
} 

.Close()と.Dispose()の差が小さく、.Close()を使用すると、2番目のインスタンスを作成することなく、再び接続を開くことができるということです。この方法は、あなたは、単にこのようにそれを使用することができますclsDBConnの

+0

clsDBConnクラスがそのインスタンスの周りでusingステートメントを使用するために必要なIDisposableインターフェイスを実装しているかどうかをどのように知っていますか? – Steve

+0

私は既に完了していると思っていましたが、そうでなければ.Close()メソッドを使うべきです。 –

+0

@Steveエラーが発生しました "usingステートメントで使用される型は暗黙的に 'System.IDisposable'に変換可能でなければなりません" –

3

あなたの接続をプールに戻すには、接続のDisposeが必要です。あなたがクラスインスタンスを完了したら、dbConn.connection.Dispose()を実行してください。またはあなたの方法への接続の作成を移動し、usingを使用します。

using(var dbConn = new clsDBConn()) 
{ 
    using(var CMD = new SqlCommand("SELECT * FROM tblEmployee", dbConn.connection)) 
    { 
     using(SqlDataReader EmplReader = CMD.ExecuteReader()) 
     { 
     while (EmplReader.Read()) 
     { 
      while(DateFrom >= DateTo) 
      { 
      //Some Reader 
      //Lots of SQL Command ExecuteNonQuery(); 
      } 
     } 
     } 
    } 
} 

注意をあなたのクラスclsDBConnIDisposableを実装し、これが機能するためには、その実装としてconnection.Dispose()を実行する必要があること。

+1

コマンドと読者も同様に扱われるべきです。 –

+0

IDisposableの実装方法は? 「usingステートメントで使用される型が暗黙的に 'System.IDisposable'に変換可能である必要があります」 –

関連する問題