【问题标题】:.NET Task: How can I create a collection of tasks that can all be executed synchronously or asynchronously?.NET 任务:如何创建一个可以同步或异步执行的任务集合?
【发布时间】:2012-08-15 13:59:50
【问题描述】:

在我的应用程序中,我向 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 来确定是否同步或异步运行任务)。但是,在使用 .StartNew() 创建的任务上调用 .RunSynchronously() 会引发异常。

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

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

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

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

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

【问题讨论】:

  • 好吧,不要使用 TaskFactory 和 StartNew(),而是创建一个新任务。并为任务的内容使用 subs 以便于调试。我不确定同步访问是否更容易调试...我宁愿对 Tasks 调用的 subs 进行单元测试。
  • 我刚刚发布了一个答案。我不想在那里偷走你的风头,但我之前已经尝试过一次。问题是我没有为我刚刚发现我需要做的每个线程调用.Start()。不过,感谢您的评论。赞成。

标签: multithreading .net-4.0 task


【解决方案1】:

您可以使用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
                )

【讨论】:

  • 这不是同步的,只是顺序的
【解决方案2】:

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

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())。你可以关注其余的。我最终会为这些创建辅助方法,但这至少显示了我使用的核心代码。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多