Multiple Parallel Task.ContinueWith执行顺序

时间:2010-11-19 15:57:38

标签: .net task-parallel-library

问题

这可能是我错过的一些简单。

让我说我做(在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使用两次。这些任务的首选执行顺序是什么?对我来说,无论是随机还是错误。

为什么?

我想这样做的原因......

  1. 创建抓取并返回数据的任务
  2. 后面是一个“排除”TaskScheduler.FromCurrentSynchronizationContext()(UI线程)上的用户界面的任务
  3. 通过将数据转换为长报告(需要很长时间)来跟踪原始数据抓取任务
  4. 返回UI线程,将该报告分配给预览控件
  5. 清理(摆脱我的进度动画等)
  6. 由于步骤4是可选

    ,因此更加复杂

    在所有这些中,我的任务向后弯曲以设置成员属性,因此UI和任务可以很好地发挥作用。也许我应该完全放弃任务结果,只是坚持Synclocking我的成员变量。它们全部只被分配一次。

    谢谢,汤姆

3 个答案:

答案 0 :(得分:11)

任务以LIFO顺序执行,以获得更好的内存位置。当然,如果您使用不同的调度程序或MS决定“修复”原始调度程序,则可以更改此项。我认为你不应该依赖这种行为。相反,您可以解开任务,以便在完成上一个任务后继续处理。否则你在等待错误的事情。您可以在此处找到更多信息:http://msdn.microsoft.com/en-us/library/ee795275.aspx

答案 1 :(得分:4)

如果你想强制执行t2和t3之间的顺序,为什么不改变是为了让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长时间运行,它们将按照你所写的方式并行执行。

无需创建自定义任务计划程序来更改此行为。

答案 2 :(得分:4)

根据您对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();

这为您提供了确定性执行,并且仍然允许您使用可选单元组成工作流程。