ExecuteReader: ¿usar la declaración es suficiente?

I'm using a web service, that is invoked every few ms, to expose some functionalities. Basically these functionalities are based on store procedures, and all my methods look like the follow:

[WebMethod]
public bool CheckMessageForMES( out int returnCode, out int messagePK, out String messageBody, out bool isRowFetched )
    {
        using ( SqlConnection connection = new SqlConnection() )
        {
            using(SqlCommand command = _dl.GetSqlCommandForStoredProcedure(DataLayer.SP_NAME, connection)){

            SqlParameter parameterReturnCode = _dl.CreateParameter("@returnCode", DbType.Int16, ParameterDirection.Output);
            SqlParameter parameterMessagePK = _dl.CreateParameter("@messagePK", DbType.Int32, ParameterDirection.Output);
            SqlParameter parameterMessageBody = _dl.CreateParameter("@messageBody", DbType.Xml, ParameterDirection.Output);
            SqlParameter parameterIsRowFetched = _dl.CreateParameter("@isRowFetched", DbType.Int16, ParameterDirection.Output);

            SqlParameter[] parameters = {
                                            parameterReturnCode,
                                            parameterMessagePK,
                                            parameterMessageBody,
                                            parameterIsRowFetched
                                        };

            command.Parameters.AddRange(parameters);

            connection.Open();

            using (SqlDataReader r = command.ExecuteReader() )
            {
                r.Close();
            }

            connection.Close();

            returnCode = int.Parse(parameterReturnCode.Value.ToString());
            messagePK = int.Parse(parameterMessagePK.Value.ToString());
            messageBody = parameterMessageBody.Value.ToString();
            isRowFetched = int.Parse(parameterIsRowFetched.Value.ToString()) > 0;
        }
 }

        return isRowFetched;
    }

Webserver process takes memory and never releases, and using VS10 tools the problem seems located in command.ExecuteReader(). Do you know why?

I'm implementing in the right way this method?

¡Gracias!

preguntado el 31 de julio de 12 a las 10:07

No llames GC.Collect manually. It's almost never a good idea and will often result in higher memory usage in the short term. -

You should also wrap your SqlCommand in a using statement, see msdn.microsoft.com/en-us/library/bb348146%28v=vs.90%29.aspx. -

@DanPuzey: I put this call only after I noticed the huge memory usage. I can remove for sure, as the behaviour is the same... -

@Monty: Done. I'm going to update code to let you see the changes -

What is the implementation behing _dl.CreateParameter() ? -

1 Respuestas

You never use the datarow you read, so you should use ExecuteNonQuery instead of the datareader.

Respondido 31 Jul 12, 11:07

Does that explain the memory leack? - George Mamaladze

If the leak is in executereader as asserted, eliminating it will logically get rid of the leak :) - Podiluska

@podiluska : The question was about memory problem. Yes ExecuteNonWuery is better in this case, but there is nothing wrong in doing that the way it's done. Could you please explain why do you think this will fix the memory problem? - George Mamaladze

@ff8mania @achitaka-san: I don't think it would cause a leak, personally, but this is a fair answer since the question suggests the leak is in ExecuteReader. - dan puzey

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.