for (int i = 1; i < 100; i++)
{
int z = i;
ThreadPool.QueueUserWorkItem((o) =>
{
Thread.Sleep(1000);
Console.Write(z.ToString());
Console.Write(Environment.NewLine);
});
}
for (int i = 1; i < 100; i++)
{
ThreadPool.QueueUserWorkItem((o) =>
{
int z = i;
Thread.Sleep(1000);
Console.Write(z.ToString());
Console.Write(Environment.NewLine);
});
这两段代码有什么区别????
}
看来上次那园友回复你没理清楚啊……
1、首先我们要明白这两段代码都创建了100个z并赋值为i;
2、这两段代码不同的地方是执行int z = i;的方式不同,
第一段代码是以同步方式执行,所以每一次i++对于z都能及时响应自增,然后再以异步的方式进行输出,尽管是异步但每个异步输出对应着第一步中创建的单一z。
第二段代码循环中是以异步方式执行,既调用ThreadPool.QueueUserWorkItem()方法后立马返回到主线程,不管插入队列的异步任务是否已经执行。这样的结果就有可能异步执行完100次ThreadPool.QueueUserWorkItem()后(即z=i已经为100了),其中的排入的队列才被分配到辅助线程进行执行,所以z的结果可能每次都输出为100(总之不会1-100都会输出吧)
请教个问题:
第二段代码循环中调用了ThreadPool.QueueUserWorkItem(),线程池中的方法不就立即执行了吗??怎么会等到i变成100再执行呢???
主要是看i,你的第一个代码是可以正确的输入1,2,3.....,100的,但是你的第2个代码就是输入100个100,但是也不一定就是100个100,还要看你定义的后台线程什么时候开始运行。
你的2个代码中for都是在主线程,也是前台线程中运行的。int z = i; 在外面的时候,for 100次,或有100个z的存在,你的100个后台线程用的是100个不同的z。
如果z在后台线程中,这个时候for 100次走完了,i=100 然后你的100个后台线程开始运行。这个是100个z都是i(100) 所有输出的结果就是相同的。
前台线程和后台线程的知识:
http://www.cnblogs.com/tianzhiliang/archive/2011/03/03/1970042.html
不知道这样的解释,你可以理解不?
光从代码上看,其实QueueUserWorkItem方法,异步执行的时候,都是访问到外部的变量(i,或者z),这个变量可能会改变。这个可以从 内存的分配来考虑,不太确定,查考一下。
第一种 访问的是z,而 z变量100份。第二种访问的是 i,最后i的值变成100,其实i变量只有一个。
能否说仔细点。感激不尽!
@彬彬@科比:
变量的问题,说的 很仔细了,不知道 哪里不明白?