为什么这段代码:
private static void UdpPortListener(UInt16 Port)
{
Console.WriteLine("Listening to port: {0}", Port);
}
static void Main(string[] args)
{
List<Thread> ts = new List<Thread>();
for(int i = 0; i < 20; i++)
{
Thread t = new Thread(() =>
{
UdpPortListener(Convert.ToUInt16(52000 + i));
});
t.IsBackground = false;
ts.Add(t);
}
ts.ForEach((x) => x.Start());
}
产生这个输出:
Listening to port: 52020
Listening to port: 52020
...
Listening to port: 52020
当我写这段代码时,我希望它能打印从 52000 开始的递增数字
最佳答案
它是您在 for
循环变量上关闭的闭包。
那个 i
变量在编译时被提升..因为它是一个循环计数器并且它实际上是在循环之外访问的(在此处的线程委托(delegate)中):
Thread t = new Thread(() =>
{
UdpPortListener(Convert.ToUInt16(52000 + i));
}); // ^^^ the compiler closes over this
这意味着,当您的 Threads
生成时,i
的值将在您的 UdpPortListener
方法中检查.. . i
的值是 for 循环中的最后一个值.. 因为循环在它之前执行。
要解决这个问题..您需要复制循环内的值:
var temp = i;
Thread t = new Thread(() =>
{
UdpPortListener(Convert.ToUInt16(52000 + temp));
});
关于C# 线程 : loop counter is printing last value only,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28628920/