1

.NET 3.5 (C#) と SQL Server 2005 (クライアント用) を実行しています。実行するコードは回帰計算を行うもので、少し複雑です。サイトで複数のページを実行すると、次のエラーが発生します。

.NET Framework execution was aborted by escalation policy because of out of memory. 
System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
System.InvalidOperationException: 

これの根本的な原因は何かを突き止めようとしています。それはデータベースの問題ですか、それとも私の C## コードですか? または、クエリを実行するときのロックとの同時実行ですか? または何か他のもの?

コードはここでエラーになっています:

erver.ScriptTimeout = 300;
        string returnCode = string.Empty;
        using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MainDll"].ToString())) {
            connection.Open();
            using (SqlCommand command = new SqlCommand(sql.ToString(), connection)) {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 300;
                returnCode = (string)command.ExecuteScalar();
                //Dispose();
            }
            //Dispose();
        }

当社の請負業者は、App_Code/sqlHelper.s ファイルで SQL 接続を支援するためのコードを多数作成しました。それらのいくつかは次のようなものです:

public static SqlDataReader GetDataReader(string sql, string connectionString, int connectionTime) {
        lock (_lock) {
            SqlConnection connection = null;
            try {
                connection = GetConnection(connectionString);
                //connection.Open();
                using (SqlCommand cmd = new SqlCommand(sql, connection)) {
                    cmd.CommandTimeout = connectionTime;
                    WriteDebugInfo("GetDataReader", sql);
                    return cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
            }
            catch (Exception e) {
                if (connection != null)
                    connection.Dispose();
                throw new DataException(sql, connectionString, e);
            }

        }
    }

どこかでメモリの割り当てを解除する必要がありますか?

4

2 に答える 2

3

問題は、何らかの理由で DataReader が閉じられていないことです。例外?メソッド ユーザーが DataReader を閉じるのを忘れていませんか?

本体の外部で使用される DataReader を返す関数は、それを外部コードに閉じる責任があるため、Reader が閉じられるという保証はありません。リーダーを閉じないと、開いた接続を再利用できません。

したがって、関数から DataReader を返すことは非常に悪い考えです!

この件に関する議論全体は、ここで見ることができます。

この関数 ( ) の使用法を探しGetDataReader、リーダーが閉じられるという保証があるかどうかを確認します。そして、最も重要なことは、最初の DataReader が閉じられる前に、このコードが再入力され、同じコレクションを使用して新しい DataReader を開く可能性がないことです。(CommandBehavior.CloseConnection に惑わされないでください。これは、DataReader が閉じられたときにのみ接続を閉じます...閉じるのに失敗しない場合にのみ)

于 2012-05-23T01:30:39.037 に答える
0

これは、データリーダーがすでに入力されているためです。データリーダー、コマンド、データセット、データテーブルを解放し、finallyブロックで接続を閉じるには常に優れた方法です。Dispose()メソッドとClose()メソッドを利用します。

于 2012-05-23T05:20:28.450 に答える