0

What is the difference between:

Task[] tasks = new Task[mylist.Count];
int i = 0;

foreach (DataTable dt in mylist)
{
            Task t = Task.Factory.StartNew(() => UpdateProductsData(dt, updateType));
            tasks[i] = t;
            i++;
}
Task.WaitAll(tasks);

and:

tasks[0] = Task.Factory.StartNew(() => UpdateProductsData(mylist[0], updateType));
tasks[1] = Task.Factory.StartNew(() => UpdateProductsData(mylist[1], updateType));
tasks[2] = Task.Factory.StartNew(() => UpdateProductsData(mylist[2], updateType));
tasks[3] = Task.Factory.StartNew(() => UpdateProductsData(mylist[3], updateType));
Task.WaitAll(tasks);

For some reason the first snippet terminates prematurely, although the second snippet behaves as expected. What needs to be changed in the first example in order to provide a dynamic implementation?

x4nd3r
  • 855
  • 1
  • 7
  • 20

1 Answers1

4

This is the classic Captured Variable In Loop issue. You need to copy the value of your loop iterator to a local variable within your loop body:

Task[] tasks = new Task[mylist.Count];
int i = 0;
foreach (DataTable dt in mylist)
{
    DataTable dtInner = dt;
    Task t = Task.Factory.StartNew(() => UpdateProductsData(dtInner, updateType));
    tasks[i] = t;
    i++;
}
Task.WaitAll(tasks);

Edit:

It may be simpler to express your code as a one-liner using Parallel.Foreach:

Parallel.ForEach(mylist, dt => UpdateProductsData(dt, updateType));
Community
  • 1
  • 1
Douglas
  • 53,759
  • 13
  • 140
  • 188