views:

17

answers:

1

I have a long running program that exectues some mySQL-Queries every 5 minutes (timed thread). After it has run for approximately 10 hours a NullReferenceException is thrown with the following stacktrace:

at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& insertedId)
   bei MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int32& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlDataReader.Close()
   at MySql.Data.MySqlClient.MySqlCommand.ResetReader()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at MyOwnProgram.Mysql.sendData(String sqlCommmand)

The sendData method is the following (lockDB is of type Object)

public void sendData(string sqlCommmand) {
            try {
                using(MySqlCommand command = connection.CreateCommand()) {
                    command.CommandTimeout = 5;
                    command.CommandText = sqlCommmand;
                    lock(lockDB) {
                        command.ExecuteNonQuery();
                    }
                }
            } catch(MySqlException e) {
                throw e;
            } catch(Exception e) {
                // do some logging
            }
        }

The connection is opened when calling the constructor of the mySQL-Class and disposed when calling the destructor or calling dispose(). Can someone tell me what I did wrong?

+2  A: 

I would recommend you leaving the connection handling to ADO.NET:

public void sendData(string sqlCommmand) 
{
    using (var con = new MySqlConnection(ConnectionString))
    using(var cmd = con.CreateCommand()) 
    {
        con.Open();
        cmd.CommandTimeout = 5;
        cmd.CommandText = sqlCommmand;
        cmd.ExecuteNonQuery();
    }
}

You no longer need the finally statement. You could add try/catch if you need to log something but make sure to propagate the exception and not consume it.

Darin Dimitrov
what stands against creating the connection when calling the constructor of the MySQL-Class?
Xelluloid
The connection string to the database.
Darin Dimitrov
can you explain it in more detail? My connection string is stored in a settings file. The connection is stored in a class variable and created by connection = new MySqlConnection(Settings.Default.ConnectionString);
Xelluloid
I mean why can't I create the connection in the construtor of the mysql class and leave it alive for the runtime of the program?
Xelluloid
ADO.NET uses a connection pool. Connections are not created everytime you sent a SQL query. They are drawn from the pool and it is better to leave this handling to the framework.
Darin Dimitrov