AseDataReader抛出System.NullReferenceException

时间:2010-08-19 05:47:39

标签: c# sybase-ase

我正在使用Sybase.AdoNet2.AseClient从Console C#应用程序访问Sybase ASE数据。并非总是如此,但我不时会得到System.NullReferenceException以下代码。

只有一个应用程序启动时效果很好,但如果我在我的机器中同时启动10个进程,则会因此异常而失败。

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

它发生在“while(reader.Read())”的行中,并且具有以下调用堆栈。

System.NullReferenceException:未将对象引用设置为对象的实例。      在Sybase.Data.AseClient1.AseDataReader.Read()
     在Sybase.Data.AseClient.AseDataReader.Read()
     在Dummy()

如果有人可以帮助我,我将非常感激。

5 个答案:

答案 0 :(得分:0)

我猜spCommand.ExecuteReader()而不是返回空读者返回null个对象。在这种情况下,我建议在阅读之前chceck它是否为null:

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

答案 1 :(得分:0)

这当然是因为spCommand.ExecuteReader返回null。但不幸的是,我无法找到为什么在SysBook Online参考中抛出Null Exception。也许尝试使用不同的命令行为

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

这样的东西
reader.ExecuteReader(CommandBehavior.CloseConnection)

或者我认为ŁukaszW.pl的答案就足够了;)

答案 2 :(得分:0)

非常感谢你的答案。

reader返回的spCommand.ExecuteReader()不是null。正如您在调用堆栈中看到的那样,异常发生在Sybase.Data.AseClient1.AseDataReader.Read()内。

以下是我从反射器获得的代码。

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

我可以看到一个NullReferenceException可以_disposed作为true投放。但不太确定是不是在我的情况下抛出异常。

答案 3 :(得分:0)

在黑暗中这是一个镜头,但我会尝试使用:

来确定对象的范围
using (AseCommand spCommand = new AseCommand())
{
     //etc..

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

由于奇怪的行为,我们总是需要调整我们的sybase对象,特别是连接对象。在任何情况下,我都不认为sybase库是管理的,所以尽可能明确地清理它是最好的做法。

答案 4 :(得分:0)

这是一个老问题,但由于我偶然发现了这个问题并找到了原因,这就是: 我的读者不是null,但它有“IsClosed = true”,因为在读取数据之前连接已关闭。

根据http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sdk_12.5.1.adonet/html/adonet/Isclosed_asadatareader_apiref.htm,一旦读者关闭,您只能调用IsClosed和RecordsAffected。