2013-07-10 99 views
-1

之间有什么区别:C#和线程池

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

和:

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

出于某种原因,第一个片段过早终止,虽然第二片段的行为与预期。第一个例子中需要改变什么才能提供动态实现?

+0

如果没有更多的上下文和更好的例子,无法分辨。 –

+0

@SimonWhitehead,但是第一个片段与第二个片段做的事情完全一样,因为“mylist”有4个元素? – user2490355

回答

4

这是经典的Captured Variable In Loop问题。您需要将循环体内的循环迭代的值复制到本地变量:

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

编辑

这可能是更简单的表达你的代码使用Parallel.Foreach一个班轮:

Parallel.ForEach(mylist, dt => UpdateProductsData(dt, updateType));