4

System.Data.DataSet とその中に 1 つのテーブルがあります。テーブルには多くの列があります。

DataSet デザイナーのスクリーンショット

特定のイベント ハンドラで、(設定時に) 既に存在するデータ行で、フィールドの 1 つに 10 進数値を設定しています。

非常にまれなケースですが、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 のセッターは作成していません)。

この問題を理解して解決するのを手伝ってくれませんか?

編集

以下は、値を設定しているコードです。

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

freeRecordList[..] DataTable はスレッド セーフではないため、 にアクセスする前に、 にアクセスした後に別のスレッドによってレコードが削除されるシナリオを簡単に想像できますthis.freeRecordList.Count

この場合、 freeRecordList.Count は、その間 => index out of bound 例外で変更されます。

したがって、もし私があなたなら、並行性の問題を見つけようとします(まれに発生するという事実は別の議論です!)

于 2013-11-07T15:40:50.680 に答える
2

テーブルで許可している小数点以下の桁数を確認し、コミットしている数値の小数点以下の桁数を確認してください。

この例外は、小数点以下の桁数が範囲外の場合にスローされる可能性があります。

于 2013-11-11T12:50:48.743 に答える