C# · 12月 26, 2021

c# – 如何在并行foreach中使用await?

因此,我试图解决这个问题,这是我晚上最好的部分.

我很幸运昨天被介绍到了parallel.foreach,它的工作方式就像我想要的那样,除了一个细节.

我有以下内容:

Parallel.ForEach(data,(d) => { try { MyMethod(d,measurements); } catch (Exception e) { // logg } });

在方法“MyMethod”中我有很多逻辑可以完成并且大部分都很好但我在api调用我获取数据的地方我使用异步任务为了能够使用“await”以便代码等到直到特定部分被执行然后继续:

private async void MyMethod(PimData pimData,IEnumerable<ProductMeasurements> measurements) { try { // alot of logic but most relevant part await Task.WhenAll(ExecuteMeasurmentAndChartLogic(pimData.ProductNumber,entity)); await Task.WhenAll(resourceImportManager.HandleEntityImageFiles(pimData.ProductType + pimData.ProductSize,SwepImageType.Png,ResourceFileTypes.ThreeD,entity,LinkTypeId.ProductResource)); await Task.WhenAll(resourceImportManager.HandleEntityImageFiles(pimData.ProductSketch,ResourceFileTypes.Sketch,LinkTypeId.ProductResource)); } catch (Exception e) { // logg } }

Problems:

1 For starters the loop finishes before all code is finished

2 Second problem is that I get “Task was canceled” in alot of api
calls

3 And third as mentioned above,the code does not wait for each method
to full execute.

我无法在ExecuteMeasurmentAndChartLogic()方法中执行所有操作
然后继续前进到下一步.

这给了我以下问题(更多问题):

在这个方法中,我创建了一个项目并将其添加到数据库中,这个项目需要我从在ExecuteMeasurmentAndChartLogic()内部完成的api调用获得的更多信息,但问题是几个项目变得疯狂并且必须等待其余数据不是我想要的.

侧面注意:我知道装箱物品并在所有数据出现之前添加到数据库中并不是最佳实践,但我正在整合PIM并且过程很简单

我想要运行几个线程但同时我希望在继续下一个方法之前为每个项执行fuill逻辑.

澄清:

几个项目正在运行

在继续下一部分代码之前,每个项目都需要handel所需的所有逻辑,并且等待着这样做.

在上面的代码中,在ExecuteMeasurmentAndChartLogic()完成之前执行resourceImportManager()方法.这是我不想要的.

而不是我使用的Parallel.ForEach:

Task task1 = Task.Factory.StartNew(() => MyMethod(data,measurements)); Task.WaitAll(task1);

但这不是一个很大的帮助

相当新的,并没有能够理解我在做错的地方.

编辑:
更新了这个问题

编辑:这是ExecuteMeasurmentAndChartLogic()的样子:

public async Task ExecuteMeasurmentAndChartLogic(string productNumber,Entity entity) { try { GrafGeneratorManager grafManager = new GrafGeneratorManager(); var graphMeasurmentList = await MeasurmentHandler.GetMeasurments(productNumber); if (graphMeasurmentList.Count == 0) return; var chart = await grafManager.GenerateChart(500,950,SystemColors.Window,ChartColorPalette.EarthTones,”legend”,graphMeasurmentList); await AddChartsAndAddToXpc(chart,productNumber); } catch (Exception e) { Console.WriteLine(e); } }

编辑:
背景到这个:
我打电话给api以获得大量数据.
对于此数据中的每个项目,我需要进行api调用并获取我应用于该项目的数据.

读完评论之后,这些评论让我以不同的方式思考.我可以遍历我的所有项目并为它们做一些小逻辑,并在任务列表中添加一个url并创建一个单独执行此任务的任务.

请保持更新

解决方法 不要使用Parralel.ForEach.让你的方法返回Task而不是void,收集所有任务并等待它们: Task.WaitAll(data.Select(d => MyMethod(d,someParam)).ToArray());