2016-03-12 75 views
2

我有这个简单的函数,作为一个任务工作,只打印数据集的值。我从主函数和索引传递数据集。问题是我只填充了2个数据集索引,但是函数总是跳过一个数据集索引,即在最后一次迭代中,它想要开始读取索引2,这是未初始化的,因此是异常。Task.Factory.StartNew()生成对象未初始化错误

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

回答

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)); 
+0

奇迹般有效。谢谢! – Abdul