开发者

Task Parallel Library - building a tree

开发者 https://www.devze.com 2023-03-14 05:01 出处:网络
I\'m having trouble with this. I\'ve got \"WorkItem\" which has a method DoWork. WorkItem can have dependencies which MUST complete before it does, otherwise it throws an exception.

I'm having trouble with this. I've got "WorkItem" which has a method DoWork. WorkItem can have dependencies which MUST complete before it does, otherwise it throws an exception.

Here's a diagram, where each item (A, B, C, etc.) is a WorkItem. The first items off the rank should thus be A, B, E, as they have no dependencies.

Task Parallel Library - building a tree

So I throw "G" to DoWorkForTask, but my exception throws itself, proving that, say, A and B haven't completed before C runs. The whole tiny project is 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开发者_如何学Go();
        }, TaskCreationOptions.AttachedToParent);
    }

Note that I've read this thread and it does not solve the issue.


This looks suspicious to me:

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

You're ignoring the child - you're just calling DoWork as many times as you have children.

Did you mean:

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

?


I'm not sure why you want to encapsulate the structure of the "workflow" into the WorkItem class. But if you don't really need to, something antecedent-based like this would work:

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"));


You may need to provide a mechanism for the child tasks to complete e.g. Task.WaitAll(

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号