Mo *_*our 5 .net c# multithreading delegates c#-4.0
我有以下方法:
static Random rr = new Random();
static void DoAction(Action a)
{
ThreadPool.QueueUserWorkItem(par =>
{
Thread.Sleep(rr.Next(200));
a.Invoke();
});
}
Run Code Online (Sandbox Code Playgroud)
现在我在这样的for循环中调用它:
for (int i = 0; i < 10; i++)
{
var x = i;
DoAction(() =>
{
Console.WriteLine(i); // scenario 1
//Console.WriteLine(x); // scenario 2
});
}
Run Code Online (Sandbox Code Playgroud)
在方案1中,输出为:10 10 10 10 ... 10
在方案2中,输出为:( 2 6 5 8 4 ... 0
随机排列0到9)
你怎么解释这个?c#不应该i
为匿名委托调用保留变量(这里)吗?
Jar*_*Par 10
这里的问题是有一个i
变量和十个实例/副本x
.每个lambda都获得对单个变量i
和其中一个实例的引用x
.每个 x
只写一次,因此每个lambda看到一个值写入它引用的值.
i
写入变量直到达到10.在循环完成之前,所有lambda都没有运行,因此它们都看到最终值为i
10
如果你按如下方式重写它,我觉得这个例子有点清楚
int i = 0; // Single i for every iteration of the loop
while (i < 10) {
int x = i; // New x for every iteration of the loop
DoAction(() => {
Console.WriteLine(i);
Console.WriteLine(x);
});
i++;
};
Run Code Online (Sandbox Code Playgroud)