Sau*_*ack 9 c# multithreading .net-3.5
我需要在一个线程中运行一个给定参数的方法.我注意到,当我运行它时,参数是错误的.对于给出的示例,我有一个int[] output数字为1-7 的数组.对于每个数字,我使用该方法创建一个线程WriteInt(i).我希望输出在任何顺序都是1-7,但我一直看到一些数字遗漏,其他人重复.发生了什么以及启动这些线程的正确方法是什么?
(该列表仅在此后加入线程)
class Program
{
static void Main(string[] args)
{
int[] output = { 1, 2, 3, 4, 5, 6, 7 };
List<Thread> runningThreads = new List<Thread>();
foreach (int i in output)
{
Thread thread = new Thread(() => WriteInt(i));
thread.Start();
runningThreads.Add(thread);
}
foreach(Thread t in runningThreads)
{
t.Join();
}
}
private static void WriteInt(int i)
{
Console.WriteLine(i);
}
}
Run Code Online (Sandbox Code Playgroud)
示例输出:
3
3
4
5
6
7
Run Code Online (Sandbox Code Playgroud)
Ree*_*sey 14
由lambda(() => WriteInt(i))创建的闭包越过变量 i,而不是i每次迭代中设置的值.当线程运行时,它使用i在该时间点内设置的值,由于foreach循环处理,该值可能已经被更改.
你需要一个临时的:
foreach (int i in output)
{
int temp = i;
Thread thread = new Thread(() => WriteInt(temp));
thread.Start();
runningThreads.Add(thread);
}
Run Code Online (Sandbox Code Playgroud)
有关正在发生的事情的详细信息,请参阅Eric Lippert的帖子标题为Closing over the loop variable被认为是有害的.
此外,在C#5(VS2012)中,这不再是foreach循环的问题.但是,它仍然会发生在for循环中.