tags:

views:

53

answers:

4

I’m using Sybase.AdoNet2.AseClient to access Sybase ASE data from a Console C# Application. Not always, but from time to time I get System.NullReferenceException With following code.

It works well with only one application started, but fails with this exception if I start 10 processes at the same time in my machine.

public void Dummy()
{
    List<string> valueList = new List<string>();

    AseParameter[] arParms = new AseParameter[1];
    arParms[0] = new AseParameter("@date", AseDbType.Date);
    arParms[0].Value = Convert.ToDateTime("1/08/2010");

    AseCommand spCommand = new AseCommand();
    spCommand.CommandType = CommandType.StoredProcedure;
    spCommand.Connection = connection;
    spCommand.CommandText = "MyStoredProcedure";

    spCommand.Parameters.AddRange(arParms);

    AseDataReader reader = spCommand.ExecuteReader();
    while (reader.Read())
    {
        if (reader["MyColumn"] != DBNull.Value)
            valueList.Add(reader["MyColumn"].ToString());
    }
}

It happens in the line of “while (reader.Read())”, and has following call stack.

System.NullReferenceException: Object reference not set to an instance of an object. at Sybase.Data.AseClient1.AseDataReader.Read()
at Sybase.Data.AseClient.AseDataReader.Read()
at Dummy()

Will be very appreciated if anybody can help me out.

A: 

I guess that spCommand.ExecuteReader() instead of returning empty reader returns null object. In this case I suggest to chceck if it's null before reading:

AseDataReader reader = spCommand.ExecuteReader();
if(reader != null)
   while (reader.Read())
   {
        if (reader["MyColumn"] != DBNull.Value)
            valueList.Add(reader["MyColumn"].ToString());
   }
ŁukaszW.pl
A: 

Well this of course because spCommand.ExecuteReader returns a null. But unfortunately i couldn't find out why the Null Exception is thrown in the SysBook Online reference. Perhaps try with a different command behavior

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sdk_12.5.1.adonet/html/adonet/Asacommand_apiref.htm

http://msdn.microsoft.com/en-us/library/system.data.commandbehavior.aspx

Something like

reader.ExecuteReader(CommandBehavior.CloseConnection)

Or i think ŁukaszW.pl's answer will suffice ;)

Ranhiru Cooray
A: 

Thanks a lot for the answers.

But "reader" returned from spCommand.ExecuteReader() is not null. The exception happens inside Sybase.Data.AseClient1.AseDataReader.Read() as you can see from the call stack.

Following is the code I got from reflector.
===
public bool Read()
{
this.OnTraceEnterEvent("Read", null);
if (this._disposed)
{
throw new NullReferenceException();
}
if (this.IsClosed)
{
throw new AseException(DriverMsgNumber.ERR_RESULTSET_DEAD, null);
}
bool state = false;
if (!this._bNoResultSet)
{
state = this.Peform_Next();
state = this.CheckSingleRow(state);
}
this.OnTraceExitEvent("Read", state);
return state;
}

I can see one NullReferenceException could be thrown with _disposed as true. But not quite sure if it's the exception getting thrown in my situation.

Sam
A: 

This is a bit of a shot in the dark, but I would try scoping the objects with Using:

using (AseCommand spCommand = new AseCommand())
{
     //etc..

     using (AseDataReader reader = spCommand.ExecuteReader())
     {
         // until end of while loop
     }
}

We have always needed to scope our sybase objects, connection objects in particular, due to strange behaviors. In any case I don't think the sybase libs are managed, so it is really best practices to clean up explicitly wherever possible.

mosheb