2013-05-09 23 views
0

我需要在完成所有任务后执行完成的行。我认为Task.WaitAll(任务)将保持小心,但在执行回调方法后,我的完成行会被执行。是否有阻止主线程直到Task aray完成它。任务数组中的Task.wait

Taskpprcessor.Batchstart(定义)

public void BatchStart(List<TaskDefinition> definition) 
     { 
      int i = 0; 
      tasks = new Task[definition.Count]; 
      definition.ForEach((a) => 
      { 

       tasks[i] = Task<TaskResult>.Factory.StartNew(() => (TaskResult)a.MethodTocall.DynamicInvoke(a.ARguments)); 
       tasks[i].ContinueWith(task => RunTaskRetObjResultIns((Task<TaskResult>)task, a.CompleteMethod));  
       i++; 

      }); 
      Task.WaitAll(tasks); 
Console.WriteLine("completed"); 
} 
+0

不要在闭包中增加外部变量。 IE,不要在闭包块外定义'i',然后在你的'foreach' lambda中增加它。这是一个有趣的方式来变得奇怪,很难调试错误。 – sircodesalot 2013-05-09 18:01:14

回答

0

我想试试这个:

public void BatchStart(List<TaskDefinition> definition) 
{ 
    Task.WaitAll(
     definition.Select 
      (a => Task<TaskResult>.Factory.StartNew(
       () => (TaskResult)a.MethodTocall.DynamicInvoke(a.ARguments)).ContinueWith(task => RunTaskRetObjResultIns((Task<TaskResult>)task, a.CompleteMethod)) 
      ).ToArray() 
     ); 
    Console.WriteLine("completed"); 
} 

我认为这个问题是ContinueWith返回一个新的任务,那就是要等待一个。你正在等待原来的任务,但不是延续。

+0

感谢dominic它的作品,你是正确的。为了避免超载我使用dynamic.invoke是一个很好的做法。谢谢sircodesalot我需要回电结果这就是为什么我采取任务。 – user2107843 2013-05-09 18:24:05

0

你可以只使用PLINQ,如:

List<Object> items = new List<Object>(); 

items.AsParallel().ForAll(obj => { 
    // Write whatever the object is to the string, but do it parallelly 
    Console.WriteLine(obj.ToString()); 
}); 

Conosle.WriteLine("Done"); 

这将并行执行所有任务,然后返回时完成。