为什么List <T> .Add抛出索引超出范围异常?

Jon*_*len -4 .net c#

当我打电话给List<T>.Add(T)它时,抛出此异常:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.Generic.List`1.Add(T item)
   at ConsoleApp5.Program.AddToList(Int32 seed) 
Run Code Online (Sandbox Code Playgroud)

我还看到Enumerable.Any针对同一列表抛出此异常。

Jon*_*len 6

这可能是由于竞争状况引起的。如果两个或多个线程同时修改列表,则列表可能会损坏。此后,以后对该列表进行的任何操作都将失败。

这是将重现它的示例。

    static List<int> TestList;
    const int ThreadCount = 10;
    const int IterationsA = 1000;

        static int count = 0;

    static void Main(string[] args)
    {
        try
        {
            while (true)
            {
                TestList = new List<int>();
                List<Thread> threads = new List<Thread>();

                for (var x = 0; x < ThreadCount; x++)
                {
                    var t = new Thread(() => AddToList(x));
                    t.Start();
                    threads.Add(t);
                }

                foreach (var t in threads)
                    t.Join();

                var b = TestList.Any(i => i == 1);

                Console.WriteLine("Pass " + DateTime.Now.ToString("hh:mm:ss.fff"));
                count += 1;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            Console.WriteLine($"Failed after {count} attempts");
        }

        Console.ReadLine();

    }

    static void AddToList(int seed)
    {
        try
        {
            var random = new Random(seed);

            for (var x = 0; x < IterationsA; x++)

            {
                TestList.Add(random.Next());
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            Console.WriteLine($"Failed after {count} attempts");
            Console.ReadLine();
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,它可能发生在第一次迭代或数千次迭代之后。

  • 你完全错了。我写这篇文章是为了帮助那些在生产中看到这种异常并且不了解出了什么问题的人。如果他们已经知道存在比赛条件,则不会搜索此问题。 (7认同)
  • 我明白了,但是这个答案至少可以显示出解决方法,否则,这不是答案 (4认同)
  • 甚至[IndexOutOfRangeException docs](https://docs.microsoft.com/zh-cn/dotnet/api/system.indexoutofrangeexception?view=netframework-4.7.2)-_“违反线程安全性。如果未以线程安全的方式访问对象,则来自不同线程的。可能会引发IndexOutOfRangeException。此异常通常是间歇性的,因为它取决于竞争条件。“ (3认同)
  • _我写这篇文章是为了帮助那些在生产中看到此异常并且不了解出了什么问题的人_否则他们可能会发现[这个问题](/sf/ask/265592001/​​ircumstance-system- collections-arraylist-add-throws-indexoutofrangee)或许多其他类似的数组 (2认同)
  • @stuartd,我的意思是,如果我们告诉所有此处的帖子“您应该检查文档”,那么应该完全没有问题。 (2认同)