4

我有一个 System.Data.DataSet 和 1 个单表。该表有许多列。

数据集设计器的屏幕截图

在某个事件处理程序中,我正在为已经存在的数据行中的一个字段设置十进制值(在设置时)。

在极少数情况下,我遇到了ArgumentOutOfRangeException异常。

消息:System.ArgumentOutOfRangeException:索引超出范围。必须是非负数且小于集合的大小。

调用堆栈:

   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)

奇怪的是,这是从框架生成的代码中发生的(当然,我没有为 DataColumn 编写 Setter)。

你能帮我理解和解决这个问题吗?

编辑

下面是我设置值的代码:

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

3 回答 3

3

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

如您所见,唯一可能出现“索引越界”异常的情况是:

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

由于那里的 DataTable 不是线程安全的,我们可以很容易地想象这样一种情况,即在访问之前freeRecordList[..] 但在访问this.freeRecordList.Count.

在这种情况下,freeRecordList.Count 会同时发生变化 => index out of bounds 异常。

因此,如果我是你,我会尝试找出并发问题(它在极少数情况下发生的事实是另一个论点!)

于 2013-11-07T15:40:50.680 回答
2

检查您在表格中允许的小数位数,并检查您提交的数字有多少位小数。

如果小数位数超出范围,则会引发此异常。

于 2013-11-11T12:50:48.743 回答
1

DataTable.GetErrors 方法

获取包含错误的 DataRow 对象数组。

于 2013-11-10T22:56:53.210 回答