在.NET中使用Task和integer的意外行为

时间:2016-11-29 10:19:15

标签: c# .net multithreading task value-type

我今天遇到了一个问题我无法解释。我有一个调用方法的任务,但整数参数似乎不像值类型那样被处理。

我可以在一个简单的环境中重现它:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Start();
        }

        private static void Start()
        {
            int numberThreads = 3;

            for (int i = 0; i < numberThreads; i++)
            {
                if (i == 3)
                {
                    // Never gets hit
                    System.Diagnostics.Debugger.Break();
                }
                Task.Run(() => DoWork(i));
            }
        }

        private static void DoWork(int index)
        {
            if (index == 3)
            {
                // index = 3
                System.Diagnostics.Debugger.Break();
            }
        }
    }
}

Start()中的(i == 3)永远不会验证为true,DoWork()中的(index == 3)始终为true。 这怎么可能?

1 个答案:

答案 0 :(得分:4)

这是因为您在这里使用变量i Task.Run(() => DoWork(i));,但是任务不会立即启动,FOR循环可以在该任务运行之前更改i。这就是为什么你可以处理i == 3内部任务。

for (int i = 0; i < numberThreads; i++)
{
    if (i == 3)
    {
         // Never gets hit
         System.Diagnostics.Debugger.Break();
    }
    Task.Run(() => DoWork(i)); <= action will executed after we exited from for loop
}

有关详细信息,请参阅此处Captured variable in a loop in C#

和ofcource我建议阅读这篇文章http://csharpindepth.com/Articles/Chapter5/Closures.aspx