任务并行库 - 构建一棵树

时间:2011-06-21 13:31:34

标签: c# tree task-parallel-library

我遇到了麻烦。我有“WorkItem”,它有一个方法DoWork。 WorkItem可以具有必须在它之前完成的依赖项,否则它会引发异常。

这是一个图表,其中每个项目(A,B,C等)都是WorkItem。因此,排名的第一项应该是A,B,E,因为它们没有依赖关系。

Diagram

所以我向DoWorkForTask抛出“G”,但是我的异常抛出了自己,证明A,B在C运行之前还没有完成。整个小项目是zipped up here.

    private void DoWorkForTask(WorkItem item)
    {
        // NOTE: item relies on Dependents to complete before it proceeds
        Task.Factory.StartNew(() => 
        {
            foreach (var child in item.Dependents)
            {
                Task.Factory.StartNew(child.DoWork, TaskCreationOptions.AttachedToParent);

                if (child.Dependents.Count > 0)
                    DoWorkForTask(child);
            }

            item.DoWork();
        }, TaskCreationOptions.AttachedToParent);
    }

请注意,我已阅读this thread但未解决此问题。

2 个答案:

答案 0 :(得分:3)

这看起来很可疑:

Parallel.ForEach(item.Dependents, child => DoWork());

你忽略了child - 你只是像生孩子一样多次调用DoWork

你的意思是:

Parallel.ForEach(item.Dependents, child => child.DoWork());

答案 1 :(得分:2)

我不确定为什么要将“工作流”的结构封装到WorkItem类中。但如果你真的不需要,像这样的先行者会起作用:

var A = Task.Factory.StartNew(
  () => Console.WriteLine("A"));
var B = Task.Factory.StartNew(
  () => Console.WriteLine("B"));
var E = Task.Factory.StartNew(
  () => Console.WriteLine("E"));
var C = Task.Factory.StartNew(
  () => { Task.WaitAll(A, B); Console.WriteLine("C"); });
var D = Task.Factory.StartNew(
  () => { Task.WaitAll(C, E); Console.WriteLine("D"); });
Task.Factory.StartNew(
  () => { Task.WaitAll(E, D); Console.WriteLine("F"); })
    .ContinueWith(a => Console.WriteLine("G"));