0
votes

Toute façon d'accéder aux résultats des tâches parallèles dès leur fin?

Actuellement, j'exécute plusieurs tâches en parallèle et placez les résultats dans une liste, à partir de laquelle j'utilise les données. Je veux exécuter toutes mes tâches en parallèle, mais dès que l'une des tâches est effectuée pour accéder directement aux données de données

Voici mon code actuel: P>

await Task.Run(async () =>
            {
                Parallel.For(0, k, i =>
                {
                    var tt = Sites.oneNews(cat, sites[i]);
                    results.Add(tt.Result);
                });
            });


0 commentaires

4 Réponses :


1
votes

Je vous suggère de lire que article - Cela m'a aidé à mettre en œuvre une logique commune dans l'un de mes projets et est également recommandée par la documentation DotNet également (je vais également lier le C # Documentation qui m'a aidé à trouver cette ressource). < / p>


0 commentaires

0
votes

Sans savoir exactement dans quel contexte vous utilisez ce code, je peux dire que vous n'avez pas besoin d'utiliser le mot clé ASYNC car l'opération que vous utilisez n'est pas asynchrone. En tout état de cause, si vous devez gérer un événement modifié de la collection, vous pouvez utiliser un ObservablectorCollection CollectionChanged et gérer le TT.RESULT Être ajouté. Mais gardez à l'esprit que puisque vous utilisez un parallélisme qui signifie que, puisque votre code n'est pas asynchrone, chaque boucle aura fini au même moment (en fonction de la manière dont l'opération est intense). Encore une fois, je ne connais pas le contexte exact, je ne peux donc pas en dire plus.


1 commentaires

Une observablecollection n'est pas du thread-coffre-fort, alors essayez de l'ajouter à partir de plusieurs threads (comme celui-ci fait ici) entraînera des erreurs.



1
votes

Il suffit de faire des résultats CODE> une collection de producteurs-consommateurs de thread-coffre-fort comme BlockingCollection . Il a getconsumingenumérable méthode code> qui renvoie un iNeuférable qui donnera un élément dès qu'une autre partie de code l'ajoute à la collection.

var results = new BlockingCollection<Result>();

var producerTask = Task.Run(() => // I removed the async here as it was not needed
{
  Parallel.For(0, k, i =>
  {
    var tt = Sites.oneNews(cat, sites[i]);
    results.Add(tt.Result);
  });

  results.CompleteAdding(); // notify any enumerable that no more items will arrive
});

foreach (var result in results.GetConsumingEnumerable())
{
  // each result will arrive here as soon as it becomes available
}

await producerTask;


2 commentaires

Dois-je faire référence à la méthode du consommateur n'importe où? J'ai mis en œuvre cela dans mon code mais le code de la méthode de consommation ne s'exécute jamais.


Oui, vous le feriez, car comment le cadre savoir qu'elle devrait l'appeler. C'était plus signifié comme exemple pour les parties distinctes des producteurs et des consommateurs. J'ai modifié ma réponse avec la façon dont il ressemblerait si vous fusionniez le producteur et le consommateur dans une méthode.



0
votes

Peut-être que je suis mal compris, mais ce qui vous empêche d'appeler simplement une méthode à partir du parallèle pour gérer les résultats tels qu'ils arrivent? Code comme ci-dessous. Nous sommes déjà sur des threads séparés, la gestion d'un ensemble de résultats ne manipulera pas la manipulation de la prochaine série, ce qui se passe dans le consommateur de @ Ckuri pour la boucle, qui gère tous les résultats sur le même fil. Cela ne concerne que si la manipulation est lente bien sûr.

Cela semble si trivial Je me demande si je n'ai pas mal compris le problème réel. P>

await Task.Run(() =>
{
    Parallel.For(0, k, i =>
    {
        var tt = Sites.oneNews(cat, sites[i]);
        var result = tt.Result;
        results.Add(result);
        // Call a method to handle the results as they arise
        HandleResult(result);
    });
});


1 commentaires

J'ai essayé cette première mais une exception est soulevée. Impossible de changer Observablecollection lors d'un événement de collection