多个并行Task.ContinueWith执行顺序
-
26-09-2019 - |
题
问题
这可能是我错过的简单事情。
假设我这样做(在loveley VB中):
Dim t1 As New Task(Sub() Debug.WriteLine("t1"))
Dim t2 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t2"))
Dim t3 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t3"))
t1.Start()
请注意 t1.ContinueWith 使用了两次。这些任务的首选执行顺序是什么?对我来说,这要么是随机的,要么是错误的。
为什么?
我想做这个的原因...
- 创建任务抓取并返回数据
- 接下来是“整理”UI 的任务
TaskScheduler.FromCurrentSynchronizationContext()
(用户界面线程) - 通过将数据转换为长报告(需要很长时间)来完成原始数据抓取任务
- 返回 UI 线程,将该报告分配给预览控件
- 清理(摆脱我的进度动画等)
由于步骤 4 是这样的事实,这变得更加复杂 选修的.
在这一切之中,我的任务正在向后弯曲以设置成员属性,以便 UI 和任务可以很好地发挥作用。也许我应该完全放弃任务结果,只坚持同步我的成员变量。毕竟它们都只分配一次。
谢谢,汤姆
解决方案
这些任务按照 LIFO 顺序执行,以获得更好的内存位置。当然,如果您使用不同的调度程序或者 MS 决定“修复”原始调度程序,则可以更改此设置。我认为您不应该依赖这种行为。相反,您可以在上一个任务完成后展开任务以继续处理该任务。否则你就在等待错误的事情。更多信息可以在这里找到: http://msdn.microsoft.com/en-us/library/ee795275.aspx
其他提示
如果您想强制 t2 和 t3 之间的顺序,为什么不直接更改 is 以便 t3 从 t2 而不是 t1 继续?
Dim t1 As New Task(Sub() Debug.WriteLine("t1"))
Dim t2 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t2"))
Dim t3 As Task = t2.ContinueWith(Sub() Debug.WriteLine("t3"))
t1.Start()
如果 t2 和 t3 长时间运行,它们将像您编写的那样并行执行。
无需创建自定义任务计划程序来更改此行为。
根据您对 Ian Mercer 的回答的评论,我会建议类似的内容
Task t1 = new Task((_)=>Console.WriteLine("t1"));
Task tn = secondTaskCondition ? t1.ContinueWith((_)=>Console.WriteLine("t2")) : t1;
Task t3 = tn.ContinueWith((_)=>Console.WriteLine("t3"));
t1.Start();
这为您提供了确定性的执行,并且仍然允许您使用可选单元来组成工作流程。
不隶属于 StackOverflow