SQL server and .NET memory constraints, allocation

2019-07-28 06:54发布

I am running .NET 3.5 (C#) and SQL Server 2005 (for our clients). The code that we run does some regression math and is a little complicated. I get the following error when I run multiple pages on our site:

.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: 

I'm trying to figure out what is the root cause of this: is it a database issue or my C## code? or is it concurrency with locks when running queries? or somethin else?

The code is erroring here:

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();
        }

Our contractor wrote a bunch of code to help with SQL connections in an App_Code/sqlHelper.s file. Some of them are like this:

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);
            }

        }
    }

Should there be some deallocation of memory somewhere?

2条回答
萌系小妹纸
2楼-- · 2019-07-28 06:58

The problem is that, for some reason, your DataReader isn't being closed. An exception? The method user didn't remember to close the DataReader?

A function that returns a DataReader to be used outside its body leaves the responsibility of closing it to outer code, so there's no guarantee that the Reader will be closed. If you don't close the reader, you cannot reuse the connection in which it was opened.

So returning a DataReader from a function is a very bad idea!

You can see a whole discussion on this subject here.

Look for the usages of this function (GetDataReader), and check if there's guarantee that the reader is getting closed. And, most importantly, that there is no possibility that this code re-enters and uses the same collection to open a new DataReader before the first is closed. (Don't be mislead by the CommandBehavior.CloseConnection. This only takes care of closing the connection when the DataReader is closed... only if you don't fail to close it)

查看更多
狗以群分
3楼-- · 2019-07-28 07:20

This is because your data reader is already filled in. Its always a better way to release the data reader, command , data set , data table and close the connection in finally block. Make use of Dispose() and Close() methods .

查看更多
登录 后发表回答