【发布时间】:2020-10-24 12:36:47
【问题描述】:
我有一个长时间运行的作业,我需要为集合中的每个项目运行一次。
我想同时完成这些工作,尽管整个程序可以等待所有工作完成。 (我以后可能会改变它,但现在,我让问题保持简单)
根据已经给出的一些帮助,我得到了以下模式:
public static void DoWork()
{
//Get a collection of items
var items = GetMyItems();
}
private async void DoStuffWithItems(ICollection<MyItem> items)
{
var tasks = items.Select (i => DoStuffWithItem(i));
await Task.WhenAll(tasks);
}
private Task DoStuffWithItem(MyItem item)
{
//LongRunningTask
return Task.Run(async () =>
{
var returnObject = await LongRunningAsyncMethod(item);
});
}
如果我理解正确的话,这仍然一次只完成一项任务 - 太没有意义了。
有人建议我将 Parallel.ForEach 与 async await 结合使用 - Parallel-ForEach 模式很简单:
public static void DoWork()
{
//Get a collection of items
var items = GetMyItems();
Parallel.ForEach(items, (item) =>
{
var returnObject = LongRunningMethod(item);
}
}
现在,如果我理解正确,我将为每个项目启动一个单独的线程来执行它的操作,但是在执行此操作时,主线程将等待
但是如果我希望程序的其余部分在 DoWork 等待 Parallel.ForEach 完成时继续执行呢?
public static void DoWork()
{
//Get a collection of items
var items = GetMyItems();
DoINeedThisMethod(items);
}
private async void DoINeedThisMethod(ICollection<MyItem> items)
{
await Task.Run(() => {
DoStuffWithItems(items);
});
}
private async void DoStuffWithItems(ICollection<MyItem> items)
{
var newobjs = new List<MyItem>();
Parallel.ForEach(items, (item) =>
{
var bc = LongRunningAsyncMethod(item);
});
}
感觉不太对劲——而且我那里有一个异步 void,这不是一个好习惯。但我在这里是正确的吗? 如果我理解正确,在 DoINeedThisMethod 中,我正在启动一个新线程(通过任务)来执行 Parallel.ForEach 调用,但是在那里使用“等待”意味着主线程现在将继续,而 Parallel.ForEach完成。
【问题讨论】:
标签: c# multithreading async-await parallel.foreach