3

Web サイトの接続プールに問題があることがわかり、追跡中です。探すべきことの 1 つは、SQLDataReaders が閉じられていることを確認することです。私の頭に浮かんだ 1 つの質問は、SQLDataReaders を返すメソッドと、それらがどのように閉じられるか (または閉じられないか) についてでした。

だからここに私が物事をセットアップする方法といくつかのメソッドの例があります:

public static SqlDataReader ExecuteReader(SqlCommand cmd)
{
    SqlConnection c = new SqlConnection(Properties.Settings.Default.DatabaseConn);
    cmd.Connection = c;
    c.Open();
    return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}

次に、「ExecuteReader()」を使用するメソッドがあります

public static SqlDataReader GetData()
{
  SqlCommand Query = new SqlCommand("select * from SomeTable");
  return ExecuteReader(Query);
}

ここで、'GetData' を呼び出す別のメソッドがあるとします。私は明らかに物事を単純化しました。

public static SqlDataReader GetMoreData()
{
  return GetData;
}

だから私の質問は、このように「GetMoreData」を呼び出すときです

SqlDataReader dr = GetMoreData();
//do some stuff with 'dr'
dr.close();

すべてのSqlDataReadersと接続が適切に閉じられていますか?

ありがとう!

4

4 に答える 4

4

説明

インターフェイスをSqlDataReader実装します。IDisposable実装するすべてのクラスで、リソースを解放するためにIDisposable呼び出すDisposeか使用する必要がありusing ます。この場合、リーダーと基になる接続を閉じます。

IDisposable インターフェイス割り当てられたリソースを解放するメソッドを定義します。

サンプル

using(SqlDataReader dr = GetMoreData()) 
{
    try
    {   
       // do your stuff
    }
    catch(Exception ex)
    {
       // handle the exception
    }
} // the reader will get closed here

また

SqlDataReader dr;
try
{   
    dr = GetMoreData();
    // do your stuff
}
catch(Exception ex)
{
   // handle the exception
}
finally
{
   // close the reader
   dr.Dispose();
}

編集

JotaBe さんの素敵なコメント

ただし、DataReader を返すメソッドを実装する場合は、メソッドの呼び出し元で using を使用する必要があります。したがって、DataReader が閉じていることを保証する方法はありません。

返品することはお勧めしSqlDataReaderませんが、これをしたい場合はこれを行う必要があります

SqlDataReader reader;
try
{
   reader = methodThatReturnsAReader();
}
catch(Exception ex)
{
   // handle the exception
}
finally
{
   // close the reader
   reader.Dispose();
}

詳しくは

于 2012-05-08T21:42:22.540 に答える
2

dr.Close() が毎回呼び出されていることが確実である限り (例外がスローされた場合でも)、はい、接続も閉じます。ただし、一般的には、そのタイプのコードを try/finally ブロックにラップすることをお勧めします。このブロックには dr.Close() ステートメントが含まれます。

もう 1 つの方法は、SqlDataReader によって実装される IDisposable インターフェイスを利用する using ステートメントです。

于 2012-05-08T21:46:11.760 に答える
0

呼び出されるすべての場所で使用されている限り、このusingステートメントはラップアラウンドされて保護されます。それは管理が難しいので、デザインを変更することで自分自身をよりよく保護することができます。SqlDataReader dr = GetMoreData()GetMoreData()

Microsoftのパターンと実践から:

"次の条件が当てはまる場合は、DataSetを使用してください。

-レイヤー間でデータをキャッシュまたは渡す必要があります。」

と比べて:

「次の条件が当てはまる場合は、DataReaderを使用してください。

-データを入れることができるビジネスコンポーネントなどのデータコンテナがあります。」

アプリケーションにはレイヤーがあり、ビジネスコンポーネントを使用していないようです。DataSetのオーバーヘッドがDataReaderよりもはるかに大きいのは事実ですが、次のことを考慮してください。

  • リークされた接続のコスト(高い、予測不可能)とデータセットの使用コスト(測定可能)
  • どのくらいのデータが必要ですか?DataSetの代わりに返すことができますDataTableDataRow

DataReaderは、データアクセスコンポーネントなどの低レベルのコードに最適ですが、アプリケーションのさまざまな部分の間で受け渡さないでください。

于 2012-05-08T22:59:28.747 に答える
0

メソッドから DataReader を返さないことをお勧めします。メソッドの呼び出し元に DataReader を閉じる責任を与えます。メソッドの呼び出し元が DataReader が閉じていることを保証しない場合、例外が発生したとしても、深刻な問題が発生します。

間違いなく、このようにしてはいけません。

状況によっては、開いている DataReader がデータベースにロックを作成する可能性があります。

唯一の例外は、メソッドがプライベートであり、すべてのメソッド呼び出し元が DataReader を閉じていることを保証する場合です。しかし、それでもかなりエラーが発生しやすいです。

于 2012-05-08T22:06:34.917 に答える