我从新的.net 4.5异步编程开始,我发现了类似下面代码的情况:我有一个同步方法,但我想进行多次调用并使其并行运行。但是,在这段代码中,所有对sync方法的调用都以id = 10运行,我不知道为什么(可能我误解了这种新方法的原因:)。
class Program
{
static void Main(string[] args)
{
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var foo = new Foo();
var fooTask = Task.Run(() => foo.FooNonAsyncMethod(i));
tasks.Add(fooTask);
}
tasks.ForEach(t => t.Wait());
Console.WriteLine("All Done!");
Console.ReadLine();
}
}
public class Foo
{
public void FooNonAsyncMethod(int id)
{
Console.WriteLine("Starting {0}", id);
Thread.Sleep(4000);
Console.WriteLine("Ending {0}", id);
}
}
// Output:
// Starting 10
// Starting 10
// Starting 10
// Starting 10
// Ending 10
// Starting 10
// Starting 10
// Ending 10
// Ending 10
// ...
答案 0 :(得分:4)
那是因为只有1个变量i
且lambda表达式绑定变量而不是值。
您可以使用以下方法解决此问题:
for (int i = 0; i < 10; i++)
{
int newI = i;
var foo = new Foo();
var fooTask = Task.Run(() => foo.FooNonAsyncMethod(newI));
tasks.Add(fooTask);
}
正如@Yuriy所提到的,这个答案有更多关于这种特殊性的信息:Is there a reason for C#'s reuse of the variable in a foreach?