如何在并行foreach中使用await? [英] How to use await in a parallel foreach?

查看:629
本文介绍了如何在并行foreach中使用await?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我将大部分时间都花在想办法解决这个问题上.

So I sepnt the better part of the night trying to figure this out.

很幸运,昨天我被介绍给parallel.foreach,它的工作方式就像我想要的一样,只是从一个细节开始.

I was fortunate to get introduced to the parallel.foreach yesterday and it works like I want it to do except from one detail.

我有以下内容:

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

        });

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

Within the method "MyMethod" I have alot of logic that gets done and most of it is fine but I make api calls where I fetch data and I use async task for this to be able to use "await" in order for the code to wait untill that specific part gets executed and then move on:

    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, SwepImageType.Png, ResourceFileTypes.Sketch, entity, LinkTypeId.ProductResource));

        }
        catch (Exception e)
        {
            // logg
        }
    }

问题:

1对于初学者,循环在所有代码完成之前结束

1 For starters the loop finishes before all code is finished

2第二个问题是我在很多api中遇到任务已取消"的问题 来电

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

3第三,如上所述,代码不等待每种方法 完全执行.

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

我无法让它执行ExecuteMeasurmentAndChartLogic()方法中的所有内容 在继续下一步之前.

I cant get it to execute everything in ExecuteMeasurmentAndChartLogic() method before moving forward to the next step.

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

This gives me the following issues (more issues):

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

In this method I create an item and add it to the db, and this item needs more info that I get from an api call that is done inside of ExecuteMeasurmentAndChartLogic() but the problem is that several items get craeated and have to wait for the rest of the data which is not what I desire.

旁注:我知道在所有数据都存在之前创建项目并添加到db并不是最佳实践,但是我正在集成到PIM中,并且此过程很微妙

我希望运行多个线程,但同时我希望在执行下一个方法之前为每个项目执行fuill逻辑.

I want several threads running but at the same time I want the fuill logic to execute for each item before moving on to the next method.

说明:

几个正在运行的项目

每个项目处理 ALL 所需的逻辑,然后再继续处理代码的下一部分,请耐心等待.

Each item handels ALL the logic it needs to handel before moving on to the next part of the code, noramly do this with await.

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

In the code above resourceImportManager() method gets executed before ExecuteMeasurmentAndChartLogic() is finished. which is what I dont want.

我使用的不是Parallel.ForEach:

Instead of a Parallel.ForEach I used :

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

但这并没有多大帮助

这是很新的知识,还无法理解我在哪里做错了.

Fairly new to this and havent been able to understand where I am doing it wrong.

更新了与​​此相关的问题

Updated the problems with this

这是ExecuteMeasurmentAndChartLogic()的样子:

this is how ExecuteMeasurmentAndChartLogic() looks like:

    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调用并获取适用于该项目的数据.

Background to this: I make a call to a api to get alot of data. For each item in this data I need to make an api call and get data that I apply to the item.

在阅读了alos的评论后,我开始以不同的方式思考.我也许可以遍历我所有的项目,并对它们做些次要的逻辑,然后在任务列表中添加一个url,并创建一个单独的任务来逐个执行该任务.

After reading comments which alos got me thinking in a diffirent way. I can perhaps loop through all my items and do minor logic for them and add a url in a task list and make a seperate task that executes this one by one.

将其保持更新

推荐答案

完全不使用Parralel.ForEach.使您的方法返回Task而不是void,收集所有任务,然后像这样等待它们:

Don't use Parralel.ForEach at all. Make your method to return Task instead of void, collect all the task and wait them like:

Task.WaitAll(data.Select(d => MyMethod(d, someParam)).ToArray());

这篇关于如何在并行foreach中使用await?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆