[英]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.