什么情况下System.Collections.ArrayList.Add会抛出IndexOutOfRangeException?

发布于 2024-09-25 01:49:43 字数 457 浏览 1 评论 0原文

我们在生产环境中遇到奇怪的错误,我们无法调试或注入日志代码。我正在尝试解决这个问题,但跟踪堆栈跟踪让我感到困惑。

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.ArrayList.Add(Object value)
   at ...

根据 MSDN Add 方法应该只抛出 NotSupportedException

我不知道这里发生了什么事。你?

We are experiencing weird bug at production environment we cannot debug nor inject logging code. I am trying to figure this up but following stack trace confuse me.

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.ArrayList.Add(Object value)
   at ...

According to the MSDN Add method should only throw NotSupportedException.

I have no idea what's going on here. Do you?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝對不後悔。 2024-10-02 01:49:43

归结为 List 不是线程安全的。在使用多个线程添加项目(没有同步)之后,在列表上进行迭代时,我遇到了 IndexOutOfRangeException 异常。下面的代码可能会在随后迭代列表时损坏项目计数并导致 IndexOutOfRangeException,

List<TradeFillInfo> updatedFills = new List<TradeFillInfo>();
Parallel.ForEach (trades, (trade) =>
{
    TradeFillInfo fill = new TradeFillInfo();

    //do something

    updatedFills.Add(fill); //NOTE:Adding items without synchronization
});

foreach (var fill in updatedFills) //IndexOutOfRangeException here sometimes
{
    //do something
}

将 Add() 与锁定语句同步将解决该问题。

lock (updatedFills)
{
    updatedFills.Add(fill);
}

It boils down to List not being thread safe. I have had IndexOutOfRangeException occuring when iterating over a list after adding items using multiple threads without synchronization. The code below could corrupt the items count and result in IndexOutOfRangeException while iterating the list subsequently,

List<TradeFillInfo> updatedFills = new List<TradeFillInfo>();
Parallel.ForEach (trades, (trade) =>
{
    TradeFillInfo fill = new TradeFillInfo();

    //do something

    updatedFills.Add(fill); //NOTE:Adding items without synchronization
});

foreach (var fill in updatedFills) //IndexOutOfRangeException here sometimes
{
    //do something
}

Synchronizing the Add() with a lock statement will fix the issue.

lock (updatedFills)
{
    updatedFills.Add(fill);
}
哆啦不做梦 2024-10-02 01:49:43

当“时,会引发 IndexOutOfRangeException尝试访问索引超出数组范围的数组元素。”

请注意,ArrayList 类不是线程安全的。在多线程场景中,竞争条件可能会导致 ArrayList 尝试在超出其范围的索引处读取/写入支持数组。

示例:一个线程减小后备数组的大小(可能通过 TrimToSize 调用),同时另一个线程将其添加到集合中。现在,如果后备数组已满,则添加线程将尝试扩展其容量(通过分配新数组)以容纳新元素。同时进行的 TrimToSize 调用可以逆转这种效果。然后,当添加线程尝试写入数组时,它认为可用的索引将不再可用,从而导致抛出异常。

修复:根据您的情况使用线程安全构造。

The IndexOutOfRangeException is thrown when "an attempt is made to access an element of an array with an index that is outside the bounds of the array."

Note that the ArrayList class is not thread-safe. It is possible that in multi-threaded scenarios, race-conditions will result in the ArrayList attempting to read/write to the backing array at indices that are outside its range.

Example: One thread reduces the size of the backing array (perhaps through a TrimToSize call) at the same time that another thread is adding to the collection. Now, if the backing array is at full capacity, the adding thread will attempt to expand its capacity (by allocating a new array) to accomodate the new element. The simultaneous TrimToSize call then reverses this effect. Then, by the time the adding thread attempts to write to the array, the index that it thought was available would no longer be, causing the exception to be thrown.

Fix: Use thread-safe constructs, as appropriate to your situation.

终弃我 2024-10-02 01:49:43

这几乎肯定是一个并发问题...您可能有两个线程同时修改集合,并且 ArrayList 类不支持并发访问。出现竞争条件,有时会导致其中一个线程尝试在数组边界之外的位置进行写入。

尝试使用 lock 语句保护对集合的所有访问,或使用集合的同步包装器(使用 ArrayList.Synchronized 方法)

That's almost certainly a concurrency issue... You probably have two threads that modify the collection at the same time, and the ArrayList class is not designed to support concurrent access. A race condition occurs, which sometimes leads one of the threads to attempt to write at a position outside the bounds of the array.

Try to protect all accesses to the collection using lock statements, or use a synchronized wrapper of the collection (using the ArrayList.Synchronized method)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文