Comment utiliser les attendent dans un parallèle foreach?

Donc je sepnt la meilleure partie de la nuit à essayer de comprendre cela.

J'ai eu la chance d'être présenté à la parallèle.foreach hier et ça fonctionne comme je le veux à faire, sauf à un détail.

J'ai le texte suivant:

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

        });

Dans la méthode "MyMethod" j'ai beaucoup de logique qui se fait et plus il est très bien mais je fais des appels de l'api d'où j'extrais les données et j'utilise async task pour cela être capable d'utiliser "en attente" pour que le code d'attendre jusqu'à ce que la partie spécifique est exécutée, puis passer:

    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
        }
    }

Problèmes:

1 Pour commencer la boucle se termine avant tout le code est fini

2 Deuxième problème est que je reçois "la Tâche a été annulée" dans beaucoup d'api
appels

3 Et la troisième comme mentionné ci-dessus, le code ne pas attendre pour chaque méthode
à la pleine exécution.

Je ne peux pas obtenir ce qu'il exécute tout en ExecuteMeasurmentAndChartLogic() la méthode
avant de passer à l'étape suivante.

Cela me donne l'questions suivantes (plus de points):

Dans cette méthode, j'ai créer un article et l'ajouter à la db, et cet élément a besoin de plus d'info que je l'obtenir à partir d'une api d'appel qui est fait à l'intérieur de ExecuteMeasurmentAndChartLogic() mais le problème est que plusieurs éléments craeated et attendre pour le reste des données qui n'est pas ce que je désire.

NOTE: je suis conscient que la mise en caisse un élément et en ajoutant à la db avant que toutes les données sont là n'est pas le plus pratique mais je suis intégration vers PIM et le processus qui est délicat

Je veux plusieurs threads en cours d'exécution, mais en même temps je veux le fuill logique à exécuter pour chaque élément avant de passer à la méthode suivante.

Préciser:

Plusieurs articles

Chaque élément handels TOUS la logique, il doit haendel avant de passer à la partie suivante du code, noramly le faire avec les attendent.

Dans le code ci-dessus resourceImportManager() la méthode est exécutée avant ExecuteMeasurmentAndChartLogic() est terminée. qui est ce que je ne veux pas.

Au lieu d'un Parallèle.ForEach j'ai utilisé :

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

mais qui n'était pas beaucoup d'une aide

Assez nouveau à cela et n'avez pas été en mesure de comprendre où je me suis fais mal.

EDIT:
Mis à jour le problèmes avec ce

EDIT: c'est de cette façon ExecuteMeasurmentAndChartLogic() ressemble à:

    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);
        }

    }

EDIT:
Contexte:
Je fais un appel à une api pour obtenir beaucoup de données.
Pour chaque élément de ces données, j'ai besoin de faire un appel d'api et d'obtenir les données que j'applique à l'élément.

Après la lecture des commentaires qui alos m'a fait penser à un diffirent façon. Je peux peut-être faire une boucle par tous mes articles et n'logique mineure pour eux et ajouter une url dans une liste de tâches et de faire une autre tâche qui s'exécute ce un par un.

Vais garder cette mise à jour

  • Utiliser le callback délégués une fois le traitement terminé.
  • Une raison particulière de MyMethod est un async void et pas un async Task?
  • pas de raison particulière, a le sens de la changer, merci de me le rappeler
  • Ce n' resourceImportManager.HandleEntityImageFiles retour. Pour un débutant il semble que vous utilisez WaitAll et WhenAll pour de simples tâches. Aussi, async void est un grand non, non, vous pourrait probablement changer Parallel.ForEach à Task.WhenAll avec certains de refactoring.
  • Aussi, en parallèle.pour le mieux pour le CPU, le travail, et la Tâche.WhenAll pour les I/O bound travail. à l'aide de async/await dans parellel est un peu un défaut de conception à mon humble avis
  • Bons resourceImportManager.HandleEntityImageFiles ne retourne rien, j'ai juste envie d'exécuter tout y avant de continuer.
  • si elle ne retourne rien, comment peut-il être un paramètre de la Tâche.WhenAll ?
  • Bons: public async Task HandleEntityImageFiles était vide avant que j'ai essayé tout ce que je peux penser à faire exécuter tout
  • À l'écho des commentaires ci-dessus, soit c'est CPU, dans ce cas, vous devez utiliser Parallel.ForEach, ou c'est IO-lié, dans ce cas, vous devez utiliser asynchrone.
  • ensuite, vous devez utiliser await HandleEntityImageFiles au lieu d'attendre await Task.WhenAll(HandleEntityImageFiles) car il renvoie à une seule Tâche. Maintenant, vous pouvez exécuter plusieurs tâches simultanées, mais alors je m'attends à quelque chose comme await Task.WhenAll(ExecuteMeasurmentAndChartLogic(pimData.ProductNumber, entity), resourceImportManager.HandleEntityImageFiles(xxx), resourceImportManager.HandleEntityImageFiles(yyy);
  • Mais je vous suggère de lire un peu plus les tutoriels avant de créer ce genre de logique que vous mélangez trop de choses et ce n'est pas te meilleur endroit pour expliquer toutes ces choses.
  • Bon j'ai fait d'utiliser attendent avant d'utiliser la Tâche.WhenAll, m'a donné le même résultat. Pour plus de lecture, je suis d'accord et j'ai, mais j'ai besoin de faire une optimisation et je suis en train d'apprendre que je vais.
  • Envisager de TPL Dataflow.
  • Bons pourriez-vous partager une réflexion sur ma solution ci-dessous.Merci!!!!

InformationsquelleAutor ThunD3eR | 2017-07-28