Question

J'ai une application qui doit parcourir en boucle toutes les lignes des fichiers texte, sur des gigaoctets. Certains de ces fichiers contiennent des dizaines ou des centaines de millions de lignes.

Un exemple de mes lectures actuelles (et synchrones) ressemble à peu près à ...

  using (FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read, FileShare.Read)) {
    using (StreamReader streamReader = new StreamReader(stream)) {
      string line;
      while (!string.IsNullOrEmpty(line = streamReader.ReadLine())) {           
        //do stuff with the line string...
      }
    }
  }

J'ai lu des articles sur les méthodes de streaming d'E / S asynchrones .Net, et je souhaite obtenir de l'aide pour deux questions spécifiques concernant ce problème.

Premièrement, vais-je améliorer mes performances en lisant de manière asynchrone ces fichiers, si j’ai besoin de l’ensemble des lignes, qui sont généralement courtes, mais de longueur variable (il n’ya pas de relation entre chacune des lignes du fichier)?

Deuxièmement, comment convertir le code ci-dessus en une lecture asynchrone, afin de pouvoir traiter chaque ligne, comme je le fais maintenant?

Était-ce utile?

La solution

Au lieu de faire en sorte que la ligne se lise en Async, vous pouvez essayer de rendre le fichier en tant que Async. Cela englobe tout le code de votre question dans un seul délégué travailleur.

    static void Main(string[] args)
    {
        WorkerDelegate worker = new WorkerDelegate(Worker);
        // Used for thread and result management.
        List<IAsyncResult> results = new List<IAsyncResult>();
        List<WaitHandle> waitHandles = new List<WaitHandle>();

        foreach (string file in Directory.GetFiles(args[0], "*.txt"))
        {
            // Start a new thread.
            IAsyncResult res = worker.BeginInvoke(file, null, null);
            // Store the IAsyncResult for that thread.
            results.Add(res);
            // Store the wait handle.
            waitHandles.Add(res.AsyncWaitHandle);
        }

        // Wait for all the threads to complete.
        WaitHandle.WaitAll(waitHandles.ToArray(), -1, false); // for < .Net 2.0 SP1 Compatibility

        // Gather all the results.
        foreach (IAsyncResult res in results)
        {
            try
            {
                worker.EndInvoke(res);
                // object result = worker.EndInvoke(res); // For a worker with a result.
            }
            catch (Exception ex)
            {
                // Something happened in the thread.
            }
        }
    }

    delegate void WorkerDelegate(string fileName);
    static void Worker(string fileName)
    {
        // Your code.
        using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (StreamReader streamReader = new StreamReader(stream))
            {
                string line;
                while (!string.IsNullOrEmpty(line = streamReader.ReadLine()))
                {
                    //do stuff with the line string...
                }
            }
        }
    }

Autres conseils

Le modèle asynchrone est BeginRead () / EndRead ().

Que vous obteniez un coup de pouce ou non dépend beaucoup de ce qui se passe au moment où vous effectuez les lectures. Votre application peut-elle faire autre chose en attendant les lectures? Si ce n’est pas le cas, le fait d’être asynchrone n’aidera pas beaucoup ...

Les lectures asynchrones finiront par faire en sorte que la tête cherche davantage pour chaque bloc. Vous obtiendrez de meilleures performances grâce à une bonne défragmentation des fichiers sur le système de fichiers et à l'utilisation de la lecture synchrone.

Comme déjà indiqué, l'envoi du traitement de la ligne à d'autres threads devrait donner un coup de fouet (en particulier sur les processeurs multicœurs)

Si les performances sont extrêmement critiques, je vous conseillerais de rechercher dans FILE_FLAG_SEQUENTIAL_SCAN . Voir détails ici

Mieux encore, écrivez une petite application C ++ qui analyse le fichier avec cet indicateur pour voir si elle améliore les performances.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top