C# 对C的循环中的多线程感到困惑#
可能重复:C# 对C的循环中的多线程感到困惑#,c#,multithreading,C#,Multithreading,可能重复: 我对多线程编程相当陌生。 当我运行下面的代码时,只有最后一个孩子被执行。 谁能告诉我发生了什么事? 多谢各位 private void Process() { Dictionary<int, int> dataDict = new Dictionary<int, int>(); dataDict.Add(1, 2000); dataDict.Add(2, 1000); dataDict.Add(3, 4000); da
我对多线程编程相当陌生。 当我运行下面的代码时,只有最后一个孩子被执行。 谁能告诉我发生了什么事? 多谢各位
private void Process()
{
Dictionary<int, int> dataDict = new Dictionary<int, int>();
dataDict.Add(1, 2000);
dataDict.Add(2, 1000);
dataDict.Add(3, 4000);
dataDict.Add(4, 3000);
foreach (KeyValuePair<int, int> kvp in dataDict)
{
Console.WriteLine("Ready for [" + kvp.Key.ToString() + "]");
Task.Factory.StartNew(() => DoSomething(kvp.Value, kvp.Key));
}
private static void DoSomething(int waitTime, int childID)
{
{
Console.WriteLine("Start task [" + childID.ToString() + "]");
Thread.Sleep(waitTime);
Console.WriteLine("End task [" + childID.ToString() + "]");
}
}
通过在lambda中使用循环变量,所有函数都有效地引用相同的变量,这是它们运行时字典的最后一项 在将循环变量传递给lambda之前,需要将其分配给循环的另一个局部变量。这样做:
foreach (KeyValuePair<int, int> kvp in dataDict)
{
var pair = kvp;
Console.WriteLine("Ready for [" + pair.Key.ToString() + "]");
Task.Factory.StartNew(() => DoSomething(pair.Value, pair.Key));
}
foreach(dataDict中的KeyValuePair kvp)
{
var对=kvp;
Console.WriteLine(“准备好[”+pair.Key.ToString()+“]);
Task.Factory.StartNew(()=>DoSomething(pair.Value,pair.Key));
}
编辑:这个小陷阱似乎在C#5中已经修复。这就是为什么它可能对其他人有效;)请参阅labroo的评论您可以通过在for循环中将kvp分配给局部变量并将变量字段Key和Value传递给DoSomething方法来防止这种行为。人们应该真正解释他们为什么否决,这似乎是对我的合理解释为什么否决,我不知道这是否是解决方案,但这是一个有效的改变。。。。。。。我也很好奇。我的答案没有任何错误。顺便说一句,Botz3000的答案意味着所有的线程都在运行…然而,当它们有机会运行时,kvp==4我也这么认为,但我不明白为什么。谢谢。我也这么想,但我不明白为什么。
foreach (KeyValuePair<int, int> kvp in dataDict)
{
var pair = kvp;
Console.WriteLine("Ready for [" + pair.Key.ToString() + "]");
Task.Factory.StartNew(() => DoSomething(pair.Value, pair.Key));
}