Task Parallel Library - building a tree
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.
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(
精彩评论