1
votes

analyse asynchrone de nombreuses chaînes

disons que j'ai le contenu du fichier divisé en

async Task Parse(ref string content)

et maintenant je voudrais faire une méthode d'analyse sur tout le contenu et à la fin je voudrais les coller en un seul variable

async Task<string> Parse(string content)
{
 //dosth
}

List<Task<string>> tasks = contents.Select(x=> Parse(x));

J'ai essayé quelque chose comme ceci:

//after parsing
foreach(var c in content)
wholeContent += c;

mais pour ce faire, je dois avoir: p >

List<string> contents

mais ce n'est pas autorisé

comment faire cela?


5 commentaires

si vous avez une analyse de tâches asynchrone () pourquoi ne pas attendre ?


La classe Parallel est bien meilleure pour cela que async / await .


L'analyse n'est généralement pas une opération liée aux E / S. Vous ne voulez pas le rendre asynchrone pour commencer. Vous pensiez probablement au traitement parallèle .


Pourquoi essayez-vous de passer la chaîne par référence? Incluez simplement la valeur analysée dans la tâche retournée (ou si elle n'est pas asynchrone, tout comme la valeur de retour de la méthode).


Il est important de comprendre que si vous analysez les chaînes en parallèle, vous ne pouvez pas contrôler la séquence dans laquelle elles sont analysées. Cela peut entraîner des résultats incohérents et imprévisibles si la séquence est importante. Cela ne signifie pas que vous ne pouvez pas les traiter en parallèle. Vous avez juste besoin d'un mécanisme pour vous assurer que la séquence d'origine est transmise à chaque opération et aux résultats afin que, une fois terminé, vous puissiez les remettre dans la séquence correcte.


3 Réponses :


2
votes

Ce n'est pas un problème asynchrone. Utilisez la classe Parallel ou PLInq:

 var results = contents.AsParallel().Select(c => /* some sync code here */);


0 commentaires

0
votes

Utilisez la classe Parallel, par exemple une simple boucle for peut être parallélisée comme telle:

    public static string Parse(string content)
        {
            return content.Replace("5", "test");
        }

Et la fonction d'analyse elle-même:

        List<string> contents = new List<string>();
        contents.Add("55");
        contents.Add("some text");
        contents.Add("a lone 5");

        ConcurrentDictionary<int, string> concurrent = new ConcurrentDictionary<int, string>();

        Parallel.For(0, contents.Count, i => concurrent[i] = Parse(contents[i]));

        foreach(string s in concurrent.Values)
        {
            Console.WriteLine(s);
        }


2 commentaires

Non, cela va casser car parsed.Add () n'est pas thread-safe.


C'est un bon point; vous pouvez (devriez) utiliser une collection simultanée à la place. J'ai édité le code.



0
votes

Comme l'a souligné une autre réponse, vous souhaitez probablement utiliser PLINQ. En supposant que vous ayez une fonction:

var result = contents.AsParallel().Select(Parse).Aggregate((x, y) => x + y);

Vous pouvez analyser et combiner les chaînes comme ceci:

string Parse(string str) { }

Cela utilise Select code> pour mapper vos chaînes via votre fonction Parse, et Aggregate pour les combiner en une chaîne par concaténation.


0 commentaires