所以我花了大半夜的时间试图解决这个问题。
我有幸被介绍到Parallel.ForEach
昨天,除了一个细节之外,它的工作原理就像我想要的那样。
我有以下内容:
Parallel.ForEach(data, (d) =>
{
try
{
MyMethod(d, measurements);
}
catch (Exception e)
{
// log
}
});
在“MyMethod”方法中,我完成了很多逻辑,其中大部分都很好,但我在获取数据的地方进行 API 调用,并使用async
任务以便能够使用await
为了让代码等待特定部分执行然后继续:
private async void MyMethod(PimData pimData, IEnumerable<ProductMeasurements> measurements)
{
try
{
// a lot 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, SwepImageType.Png, ResourceFileTypes.Sketch, entity, LinkTypeId.ProductResource));
}
catch (Exception e)
{
// log
}
}
Problems:
1 对于初学者来说,循环在所有代码完成之前完成
2 第二个问题是我在很多 API 调用中收到“任务已取消”
3 第三,如上所述,代码不会等待每个方法完全执行。
我无法让它执行所有内容ExecuteMeasurmentAndChartLogic()
方法
在继续下一步之前。
这给我带来了以下问题(更多问题):
在此方法中,我创建一个项目并将其添加到数据库中,该项目需要我从在内部完成的 API 调用中获取的更多信息ExecuteMeasurmentAndChartLogic()
但问题是创建了几个项目,并且必须等待其余的数据,这不是我想要的。
旁注:我知道在所有数据之前创建一个项目并添加到数据库并不是最佳实践,但我正在集成 PIM,其过程很微妙
我希望运行多个线程,但同时我希望在继续下一个方法之前为每个项目执行完整的逻辑。
澄清:
多个项目正在运行
每个项目处理ALL在继续代码的下一部分之前需要处理的逻辑。通常这样做await
.
在上面的代码中resourceImportManager()
方法先执行ExecuteMeasurmentAndChartLogic()
完了,这是我不想要的。
代替Parallel.ForEach
我用了 :
Task task1 = Task.Factory.StartNew(() => MyMethod(data, measurements));
Task.WaitAll(task1);
但这并没有多大帮助。
对此相当陌生,无法理解我哪里做错了。
编辑:
更新了这个问题
编辑:这就是方式ExecuteMeasurmentAndChartLogic()
looks:
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, entity, productNumber);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
编辑:
背景:
我调用 API 来获取大量数据。对于此数据中的每个项目,我需要进行 API 调用并获取应用于该项目的数据。
阅读评论后,这也让我以不同的方式思考。我也许可以循环遍历所有项目并为它们执行较小的逻辑,并在任务列表中添加 URL 并创建一个单独的任务来逐一执行此任务。
将保持更新