为什么循环中的任务工厂打印超出循环索引? [英] Why task factory in loop prints beyond loop index?

查看:33
本文介绍了为什么循环中的任务工厂打印超出循环索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习在 C# 中使用任务并行库 (TPL),并编写了以下代码(您可以复制并运行它).

I am learning to use the Task Parallel Library(TPL) in C#, and wrote the following code (you can copy-past it and run it).

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 的值开始迭代.但是,我得到的输出是这样的:

in the for loop, the counter index i cannot start an iteration with a value of i = 6. However, the output i got is this:

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

然而,在另一个发布中(代码没有改变),我得到了这个:

However, in another launch(didn't change in the code), i got this:

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 Debugged the code, and found that i value is: 0,1,3,4,5,6

这是怎么发生的?

为什么我在循环中得到 (i = 6)?

我的代码有什么问题吗?

注意:我使用的是 Visual Studio 2010

Note: I'm using visual studio 2010

推荐答案

因为存在闭包问题.您需要将变量 i 复制到临时变量中.

because there is a closure problem. you need to copy the variable i in temporary variable.

for (int i = 0; i < 6; i++)
{
    var tempi = i;
    var t01 = Task.Factory.StartNew(() => Console.WriteLine("in loop: i = {0}", tempi));
}

因为您的任务在另一个线程中开始.但是您不会在当前线程中等待该任务.所以程序会回来并增加计数器.由于您创建的委托使用原始计数器,因此它打印 6.因为数到 6 比创建新任务要快得多.

Because your task starts in another thread. but you dont wait for that task in current thread. so the program will comeback and will increment the counter. since the delegate you have created uses the original counter then it prints 6. because counting to 6 is done much faster than creating a new task.

当您使用调试器时,新任务将有机会在您继续增加计数器之前打印该值,

When you use debugger the new task will get a chance to print the value before you continue to increment the counter,

这篇关于为什么循环中的任务工厂打印超出循环索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆