我遇到了麻烦。我有“WorkItem”,它有一个方法DoWork。 WorkItem可以具有必须在它之前完成的依赖项,否则它会引发异常。
这是一个图表,其中每个项目(A,B,C等)都是WorkItem。因此,排名的第一项应该是A,B,E,因为它们没有依赖关系。
所以我向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但未解决此问题。
答案 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"));