Why does List<T>.Add throw an index out of range exception?

时间:2019-04-16 22:21:58

标签: c# .net

When I call List<T>.Add(T) it throws this exception:

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) 

I've also see this exception thrown by Enumerable.Any against the same list.

1 个答案:

答案 0 :(得分:6)

This can be caused by a race condition. If two or more threads modify the list at the same time, it can become corrupted. After that point, any future operations against the list will fail.

Here is a sample that will reproduce it.

    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();
        }
    }

Note that it may happen on the first iteration or after thousands of iterations.