Abdul
Abdul

Reputation: 77

Task.Factory.StartNew() generating object not initialzed error

I have this simple function,working as a task, that only print the values of a dataset. I pass the dataset from main function, and the index. The problem is that i have populated only 2 dataset index, however the function always jumps one ahead, i.e. in the last iteration it would want to start reading index 2, which is uninitialized and therefore the exception.

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

and the function is

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

In the last iteration when i print 1 however in function if i print a it would be 2.

Upvotes: 2

Views: 80

Answers (1)

Douglas
Douglas

Reputation: 54927

I assume you are aware of the dangers of captured counter variables in lambda closures, since you attempt to avoid the issue by assigning the counter to a locally-scoped variable. However, your assignment is happening too late – by the time the task starts and copies the value, the counter might already have been incremented by the next iteration. To properly avoid the issue, you need to copy the value before the task, not within it:

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

If you just need to perform a parallel loop, you could alternatively use:

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

Upvotes: 3

Related Questions