Task.Factory.StartNew()生成对象未初始化错误

时间:2016-03-12 17:27:46

标签: c# multithreading task-parallel-library

我有一个简单的功能,作为一项任务,只打印数据集的值。我从main函数和索引传递数据集。问题是我只填充了2个数据集索引,但是该函数总是先前跳过一个,即在最后一次迭代中,它希望开始读取索引2,这是未初始化的,因此是异常。

for (int i = 0; i < 2; i++)
{
   tasks.Add(Task.Factory.StartNew(() => {
       int a = i;                     
       showNodeID(dataSet,a);
       }));
}

,功能是

private static void showNodeID(DataSet[] ds, int a)
{
    Console.WriteLine(a.ToString());
    Console.WriteLine(ds[a].GetXml());
}   //END

在最后一次迭代中,当我打印1但是在功能中如果我打印它将是2.

1 个答案:

答案 0 :(得分:3)

我假设你知道在lambda闭包中捕获的计数器变量的危险,因为你试图通过将计数器分配给本地范围的变量来避免这个问题。但是,您的分配发生得太晚 - 在任务开始并复制值时,计数器可能已经在下一次迭代时增加。要正确避免此问题,您需要在任务之前复制值,而不是在其中:

for (int i = 0; i < 2; i++)
{
    int a = i;                     
    tasks.Add(Task.Factory.StartNew(() => 
    {
        showNodeID(dataSet, a);
    }));
}

如果您只需要执行并行循环,您也可以使用:

Parallel.For(0, 2, i => showNodeID(dataSet, i));