.NET任务:如何创建可以同步或异步执行的任务集合?

时间:2012-08-15 13:59:51

标签: multithreading .net-4.0 task

在我的应用程序中,我将一堆操作添加到List(Of Task),如下所示:

Dim Tasks As New List(Of Task)

Tasks.Add(Task.Factory.StartNew(Sub()
                                    System.Threading.Thread.Sleep(3000)
                                End Sub))

Tasks.Add(Task.Factory.StartNew(Sub()
                                    System.Threading.Thread.Sleep(3000)
                                End Sub))

Task.WaitAll(Tasks.ToArray())

当我呼叫Task.WaitAll(Tasks.ToArray())时,它会按预期同时执行所有任务。但是,通过线程方法调试/步进有点困难,所以我希望能够同步执行所有这些(我在配置文件中创建了一个AppSetting,我可以用来确定是否要同步或异步运行任务)。但是,在使用.RunSynchronously()创建的任务上调用.StartNew()会引发异常。

我应该如何构建这个任务列表,以便在同步和异步执行之间切换?

编辑:从概念上讲,这就是我想要做的事情:

If ConfigurationManager.AppSettings("ExecuteAsynchronously") = "1" Then
    Task.WaitAll(Tasks.ToArray())
Else
    Task.WaitAllAsynchronously(Tasks.ToArray())
End If

我知道.WaitAllAsynchronously()不存在,但您仍然可以看到我想要实现的最终结果。如果我必须创建一个名为.WaitAllAsynchronously()的扩展方法,它遍历每个任务并同步执行,那就是我要做的。

由于.StartNew()不支持同步执行,我需要构建我的任务列表而不实际启动它们,但是它支持同步和异步执行。

2 个答案:

答案 0 :(得分:0)

您可以使用Parallel.Invoke并将其设置为使用单个帖子。

Dim po AS new ParallelOptions()
po.MaxDegreeOfParallelism = 1

Parallel.Invoke(po,
                Sub()
                   System.Threading.Thread.Sleep(3000)
                End Sub,
                Sub()
                   System.Threading.Thread.Sleep(3000)
                End Sub
                )

答案 1 :(得分:0)

我想出了一种使用Tasks做我想做的事情的方法。我打算删除我的问题,但我觉得其他人可能从中受益,所以这就是我所做的:

Dim ExecuteSynchonously As Boolean = True

Dim Tasks As New List(Of Task)

Tasks.Add(New Task(Sub()
                       System.Threading.Thread.Sleep(3000)
                   End Sub))

Tasks.Add(New Task(Sub()
                       System.Threading.Thread.Sleep(3000)
                   End Sub))

'will create helper extension methods for these
If ExecuteSynchonously Then
    Tasks.ForEach(Sub(t)
                      t.RunSynchronously()
                  End Sub)
Else
    Tasks.ForEach(Sub(t)
                      t.Start()
                  End Sub)
    Task.WaitAll(Tasks.ToArray)
End If

首先,我通过向集合中添加非启动任务来构建集合(而不是.StartNew())。你可以跟着其余的。我将最终为这些创建辅助方法,但这至少显示了我使用的核心代码。

如果有人看到更有效的方法,请告诉我。