如何在嵌套任务中使用子任务

时间:2017-06-01 11:31:04

标签: .net vb.net multithreading parallel-processing task

我使用parallel.For运行嵌套任务。但是对于基于某些条件的一次迭代,我必须运行附加该特定迭代任务的子任务。

下面是我的示例代码。

  Dim tsk As Task = Task.Run(Function() Parallel.For(0, dgvDataTables.Rows.Count, New ParallelOptions() With {.MaxDegreeOfParallelism = 1},
  Sub(index)
      // performs certion action
    if expression valid then
           Dim childTask As Task = Task.Factory.StartNew(Sub()                                                                                                                                                  
             // performs action                                                                                                                           
End Sub, CancellationToken.None, TaskCreationOptions.AttachedToParent)
   end if
  End Sub)

当我运行我的代码时,一旦所有迭代完成,子任务就会被执行。

如何将子任务附加到嵌套的父任务?

感谢任何帮助。

TIA

1 个答案:

答案 0 :(得分:0)

这种情况下的解决方案是使用Parallel.For的不同重载。有一个允许您传递局部变量。这是你需要的。

Parallel.For(Of TLocal)

所以你在外部任务中基本上想做的是:

Dim childTasks As New List(Of Task)
Parallel.For(0, dgvDataTables.Rows.Count,
             New ParallelOptions() With {.MaxDegreeOfParallelism = 1},
             Function() New List(Of Task),
             Function(index, state, taskList)
               // performs certion action
               If expression valid Then
                 Dim childTask = Task.Run(Sub()
                                            // performs action 
                                          End Sub)  
                 taskList.Add(childTask)
               End If
               Return taskList                      
             End Function,
             Sub(taskList)
               SyncLock childTasks
                 childTasks.AddRange(taskList)
               End SyncLock
             End Sub)
Task.WaitAll(childTasks.ToArray())

所以基本的想法是将所有任务收集到一个列表中,并在Parallel.For完成后等待所有收集的任务。

我故意选择在此处使用Task.WaitAll,因为使用AwaitTask.WhenAll可能会导致与Parallel.For一起出现问题。我倾向于避免混合使用Parallel函数和Async/Await

所有这些说完了之后,我必须警告您,此代码可能会产生巨大的开销,具体取决于您创建的Task个实例的数量。如果有太多活动的运行Task实例,则应用程序的性能将会中断。