任务类无法获得正确的值

时间:2014-01-24 07:47:12

标签: c# asynchronous task

在For迭代中,我将一个Task放入其中。每项任务都有自己的工作。代码如下:

 List<Task> lst_tsk = new List<Task>();
            List<int> lst_item = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            foreach (var item in lst_item)
            {
                Task tsk = new Task(() =>
                {
                    Console.WriteLine(item);
                });
                lst_tsk.Add(tsk);
                tsk.Start();
            }

            foreach (var t in lst_tsk)
            {
                if (t.IsCompleted == false)
                    t.Wait();
            }

我希望它打印出1,2,3,4,5,6,7,8,9,10。 但它有效并打破了我的想法。 结果是10,10,10,10,10,10,10,10,10,10。

那么如何编辑代码以使事情正确?

1 个答案:

答案 0 :(得分:7)

这是关闭和捕获变量的问题,问题在article by Eric Lippert

中完整解释

要解决您的问题,请在每次迭代中将项目值复制到一个新变量中:

 List<Task> lst_tsk = new List<Task>();
        List<int> lst_item = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        foreach (var item in lst_item)
        {
            var value = item;
            Task tsk = new Task(() =>
            {
                Console.WriteLine(value);
            });
            lst_tsk.Add(tsk);
            tsk.Start();
        }

        foreach (var t in lst_tsk)
        {
            if (t.IsCompleted == false)
                t.Wait();
        }

备注:此问题已通过C#5.0修复:

  

在C#5中,a的循环变量   foreach将在逻辑上位于循环内,因此闭包将会   每次关闭变量的新副本