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



在我的应用程序中,我向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())时,它会按预期同时执行所有任务。 但是,调试/单步执行线程方法有点困难,因此我希望能够同步执行所有这些方法(我将在我的配置文件中创建一个 AppSet,我可以用来确定是同步运行任务还是异步运行任务)。 但是,对使用 .StartNew() 创建的任务调用 .RunSynchronously() 会引发异常。

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

编辑:从概念上讲,这是我想做的:

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

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

由于.StartNew()不支持同步执行,因此我需要在不实际启动任务的情况下构建任务列表,而是以一种同时支持同步和异步执行的方式构建任务列表。

您可以使用

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
                )

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

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())来构建集合。 您可以遵循其余部分。 我最终将为这些创建帮助程序方法,但这至少显示了我使用的核心代码。

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

最新更新