简体   繁体   English

当多线程时,循环索引超出范围ArgumentOutOfRangeException

[英]For loop index out of range ArgumentOutOfRangeException when multithreading

I'm getting some strange behavior... when I iterate over the dummyText List in the ThreadTest method I get an index out of range exception ( ArgumentOutOfRangeException ), but if I remove the threads and I just print out the text, then everything works fine. 我得到了一些奇怪的行为......当我在ThreadTest方法中迭代dummyText List ,我得到一个超出范围异常的索引( ArgumentOutOfRangeException ),但是如果我删除了线程并且我只是打印出文本,那么一切正常精细。

This is my main method: 这是我的主要方法:

public static Object sync = new Object();
static void Main(string[] args)
{
    ThreadTest();
    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

This method throws the exception: 此方法抛出异常:

private static void ThreadTest()
{
    Console.WriteLine("Running ThreadTest");
    Console.WriteLine("Running ThreadTest");
    List<String> dummyText = new List<string>()
    { "One", "Two", "Three", "Four", "Five", 
      "Six", "Seven", "Eight", "Nine", "Ten"};

    for (int i = 0; i < dummyText.Count; i++)
    {
        Thread t = new Thread(() => PrintThreadName(dummyText[i])); // <-- Index out of range?!?
        t.Name = ("Thread " + (i));
        t.IsBackground = true;
        t.Start();
    }
}

private static void PrintThreadName(String text)
{
    Random rand = new Random(DateTime.Now.Millisecond);
    while (true)
    {
        lock (sync)
        {
            Console.WriteLine(Thread.CurrentThread.Name + " running " + text);
            Thread.Sleep(1000+rand.Next(0,2000));
        }
    }
}

This does not throw the exception: 这不会抛出异常:

private static void ThreadTest()
{
    Console.WriteLine("Running ThreadTest");
    List<String> dummyText = new List<string>()
    { "One", "Two", "Three", "Four", "Five", 
      "Six", "Seven", "Eight", "Nine", "Ten"};

    for (int i = 0; i < dummyText.Count; i++)
    {
        Console.WriteLine(dummyText[i]); // <-- No exception here
    }
}

Does anybody know why this is happening? 有人知道为什么会这样吗?

When you pass a local variable into a thread or ThreadPool delegate through a closure, you need to make a copy of the variable. 当您通过闭包将局部变量传递给线程或ThreadPool委托时,您需要复制该变量。 As in: 如:

for (int i = 0; i < dummyText.Count; i++)
{
    int index = i;
    Thread t = new Thread(() => PrintThreadName(dummyText[index]));
    // ...
}

If you don't do this, then the variable basically gets passed in by reference, and the index will exceed the bounds of the array at the very end of the for loop (which may happen long before the closure is ever executed). 如果你不这样做,那么变量基本上是通过引用传入的,并且索引将超过for循环末尾的数组边界(这可能在执行闭包之前很久就会发生)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 LINQ | ArgumentOutOfRangeException:索引超出范围 - LINQ | ArgumentOutOfRangeException: Index was out of range 访问Collection时是否ArgumentOutOfRangeException,即使索引未超出范围? - ArgumentOutOfRangeException when accessing a Collection, even though index is not out of range? Unity3D ArgumentOutOfRangeException:索引超出范围 - Unity3D ArgumentOutOfRangeException: Index was out of range System.ArgumentOutOfRangeException:索引超出范围 - System.ArgumentOutOfRangeException: Index was out of range C#-ArgumentOutOfRangeException:索引超出范围-2种形式 - c# - ArgumentOutOfRangeException: Index was out of range - 2 Forms System.ArgumentOutOfRangeException:索引超出范围 C# 中的错误 - System.ArgumentOutOfRangeException: Index was out of range Error in C# C#System.ArgumentOutOfRangeException:索引超出范围 - C# System.ArgumentOutOfRangeException:Index was out of range 奇怪的“索引超出范围”(多线程问题) - Strange 'Index was out of range' (Multithreading issue) System.ArgumentOutOfRangeException: &#39;指定的参数超出了有效值的范围。 参数名称:asp.net中的index&#39; - System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: index' in asp.net ArgumentOutOfRangeException-索引超出范围。 必须为非负数且小于集合的大小 - ArgumentOutOfRangeException - index was out of range. Must be non-negative and less than the size of the collection
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM