我正在学习在C#中使用任务并行库(TPL),并编写了以下代码(您可以复制它并运行它).
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace parallelTaskLibrary { class Program { static void Main(string[] args) { for (int i = 0; i < 6; i++) { var t01 = Task.Factory.StartNew(() => Console.WriteLine("in loop: i = {0}", i)); } Console.WriteLine("press any key to terminate..."); Console.ReadKey(); } } }
在for
循环中,计数器索引i
无法启动值为的迭代i = 6
.但是,我得到的输出是这样的:
press any key to terminate... in loop: i = 6 in loop: i = 6 in loop: i = 6 in loop: i = 6 in loop: i = 6 in loop: i = 6
但是,在另一次发布中(代码中没有改变),我得到了这个:
in loop: i = 1 in loop: i = 1 in loop: i = 2 in loop: i = 3 in loop: i = 4 in loop: i = 5 press any key to terminate...
这似乎是合理的......
我调试了代码,发现i
值是:0,1,3,4,5,6
那是怎么发生的?
为什么我在循环中得到(i = 6)?
我的代码有什么问题吗?
注意:我正在使用visual studio 2010
因为有一个关闭问题.你需要i
在临时变量中复制变量.
for (int i = 0; i < 6; i++) { var tempi = i; var t01 = Task.Factory.StartNew(() => Console.WriteLine("in loop: i = {0}", tempi)); }
因为您的任务从另一个线程开始.但是你不要在当前的线程中等待那个任务.所以程序会回来并增加计数器.因为您创建的委托使用原始计数器然后打印6
.因为计数到6比创建新任务要快得多.
当您使用调试器时,新任务将有机会在继续递增计数器之前打印该值,