简体   繁体   中英

Why am I getting this exception

I have a System.Data.DataSet and 1 single table in it. The table has many columns.

DataSet Designer的屏幕截图

In a certain event handler, I am setting a decimal value for one of the fields, in a data row which is already existing (at the time of setting).

In a very rare case, I am getting a ArgumentOutOfRangeException exception.

Message: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

Call Stack:

   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at System.Data.RecordManager.NewRecordBase()
   at System.Data.DataTable.NewRecord(Int32 sourceRecord)
   at System.Data.DataRow.BeginEditInternal()
   at System.Data.DataRow.set_Item(DataColumn column, Object value)
   at CPITS.Data.OrdersRow.set_ExecutionPrice(Decimal value)

Strange thing is, this is happening from the code which the framework has generated (Of course, I didn't write the Setter for the DataColumn).

Can you please help me understand & fix this problem?

EDIT

Below is the code where I am setting value:

void ibclient_OrderStatus(object sender, OrderStatusEventArgs e)
{
    Data.OrdersRow drOrders = data.Orders.FindByOrderId(e.OrderId);

    if (drOrders != null)
    {
        drOrders.FilledQuantity = e.Filled;
        drOrders.ExecutionPrice = e.AverageFillPrice; //Sporadic Exception when setting a decimal value
    }
}

Here is de decompiled code of RecordManager.NewRecordBase

internal int NewRecordBase()
{
  int num;
  if (this.freeRecordList.Count != 0)
  {
    num = this.freeRecordList[this.freeRecordList.Count - 1];
    this.freeRecordList.RemoveAt(this.freeRecordList.Count - 1);
  }
  else
  {
    if (this.lastFreeRecord >= this.recordCapacity)
      this.GrowRecordCapacity();
    num = this.lastFreeRecord;
    ++this.lastFreeRecord;
  }
  return num;
}

as you can see, the only case where you could have a "index out of bounds" exception is here:

num = this.freeRecordList[this.freeRecordList.Count - 1];

since there DataTable is not thread safe, we could easily imagine a scenario where a record is removed by another thread before accessing the freeRecordList[..] but after having accessed to this.freeRecordList.Count .

In this case, freeRecordList.Count would have changed in the meanwhile => index out of bounds exception.

Thus, if I were you, I would try to find a concurrency issue (the fact that it happens in rare cases is another argument !)

Check the number of decimal places you are allowing in your table and check how many decimals the number you are committing has.

This exception can be thrown if the number of decimals is out of range.

DataTable.GetErrors Method

Gets an array of DataRow objects that contain errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM