我是C#线程和任务的新手,我正在尝试开发工作流程,但没有成功,可能是因为我将任务与迭代混合......
重点是:
我有一堆列表,每个列表中都有一些要做的事情,并且需要让它们尽可能多地并行运行并且阻塞性更小,并且只要每个subBunchOfThingsTodo完成(这意味着内部要做的每件事都是平行完成的。它做了一些事情(DoSomethingAfterEveryThingToDoOfThisSubBunchOfThingsAreDone())。
e.g:
bunchOfSubBunchsOfThingsTodo
subBunchOfThingsTodo
subBunchOfThingsTodo
subBunchOfThingsTodo
这就是我尝试的方式,但不幸的是,每次迭代都会等待前一个onOfThingsToDo,我需要它们并行工作。 事情要做同样的事情,他们等待前一件事开始......
List<X> bunchOfSubBunchsOfThingsTodo = getBunchOfSubBunchsOfThingsTodo();
foreach (var subBunchOfThingsToDo in bunchOfSubBunchsOfThingsTodo)
{
int idSubBunchOfThingsToDo = subBunchOfThingsToDo.ThingsToDo.FirstOrDefault().IdSubBunchOfThingsToDo;
var parent = Task.Factory.StartNew(() =>
{
foreach (var thingToDo in subBunchOfThingsToDo.ThingsToDo)
{
var child = Task.Factory.StartNew(() =>
{
//Do some stuff with thingToDo... Here I call several bussines methods
});
}
});
parent.Wait();
DoSomethingAfterEveryThingToDoOfThisSubBunchOfThingsAreDone(idSubBunchOfThingsToDo);
}
答案 0 :(得分:1)
您可能想尝试使用 Task.WhenAll 并使用linq来生成一系列热门任务:
static async void ProcessThingsToDo(IEnumerable<ThingToDo> bunchOfThingsToDo)
{
IEnumerable<Task> GetSubTasks(ThingToDo thing)
=> thing.SubBunchOfThingsToDo.Select( async subThing => await Task.Run(subThing));
var tasks = bunchOfThingsToDo
.Select(async thing => await Task.WhenAll(GetSubTasks(thing)));
await Task.WhenAll(tasks);
}
通过这种方式,您可以在单独的任务上运行每个 subThingToDo ,并且每个 thingToDo
只能获得由所有子任务组成的一个任务修改强>
在此示例中,ThingToDo是一个相当简单的类:
class ThingToDo
{
public IEnumerable<Action> SubBunchOfThingsToDo { get; }
}
答案 1 :(得分:-2)
只需更改代码,您就可以尝试这种方式:
var toWait = new List<Task>();
List<X> bunchOfSubBunchsOfThingsTodo = getBunchOfSubBunchsOfThingsTodo();
foreach (var subBunchOfThingsToDo in bunchOfSubBunchsOfThingsTodo)
{
int idSubBunchOfThingsToDo = subBunchOfThingsToDo.ThingsToDo.FirstOrDefault().IdSubBunchOfThingsToDo;
var parent = Task.Factory.StartNew(() =>
{
Parallel.ForEach(subBunchOfThingsToDo.ThingsToDo,
thingToDo =>
{
//Do some stuff with thingToDo... Here I call several bussines methods
});
});
//parent.Wait();
var handle = parent.ContinueWith((x) =>
{
DoSomethingAfterEveryThingToDoOfThisSubBunchOfThingsAreDone(idSubBunchOfThingsToDo);
})
.Start();
toWait.Add(handle);
}
Task.WhenAll(toWait);
感谢downvoters团队,建议“好”&#39;溶液:
var bunchOfSubBunchsOfThingsTodo = getBunchOfSubBunchsOfThingsTodo();
var toWait = bunchOfSubBunchsOfThingsTodo
.Select(subBunchOfThingsToDo =>
{
return Task.Run(() =>
{
int idSubBunchOfThingsToDo = subBunchOfThingsToDo.ThingsToDo.FirstOrDefault().IdSubBunchOfThingsToDo;
Parallel.ForEach(subBunchOfThingsToDo.ThingsToDo,
thingToDo =>
{
//Do some stuff with thingToDo... Here I call several bussines methods
});
DoSomethingAfterEveryThingToDoOfThisSubBunchOfThingsAreDone(idSubBunchOfThingsToDo);
});
});
Task.WhenAll(toWait);