任务类无法获得正确的值

roa*_*oul 1 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();
            }
Run Code Online (Sandbox Code Playgroud)

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

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

Ale*_*exH 7

这是关闭和捕获变量的问题,这个问题在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();
        }
Run Code Online (Sandbox Code Playgroud)

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

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