Как выполнить асинхронное чтение файлов в C # 2.0? - PullRequest
4 голосов
/ 29 апреля 2009

У меня есть приложение, которое должно перебирать все строки в текстовых файлах размером более гигабайта. Некоторые из этих файлов содержат 10 или 100 миллионов строк.

Пример моего текущего (и синхронного) чтения выглядит примерно так ...

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

Я прочитал кое-что о методах потоковой передачи асинхронного ввода-вывода .Net, и мне нужна помощь с двумя конкретными вопросами, касающимися этой проблемы.

Во-первых, получу ли я повышение производительности за счет асинхронного чтения этих файлов, если мне понадобится полнота каждой строки, обычно короткой, но разной длины (между каждой строкой в ​​файле нет взаимосвязи)?

Во-вторых, как мне преобразовать приведенный выше код в асинхронное чтение, чтобы я мог обрабатывать каждую строку построчно, как сейчас?

Ответы [ 4 ]

7 голосов
/ 29 апреля 2009

Вместо того, чтобы строка читала Async, вы можете попробовать сделать так, чтобы файл читал Async. Это включает весь код вашего вопроса в одном рабочем делегате.

    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...
                }
            }
        }
    }
1 голос
/ 29 апреля 2009

Асинхронное чтение просто приведет к тому, что голова будет искать больше для каждого блока. Вы получите лучшее повышение производительности благодаря хорошей дефрагментации файлов в файловой системе и использованию синхронного чтения.

Как уже указывалось, отправка обработки строки другим потокам должна дать импульс (особенно для многоядерных процессоров)

1 голос
/ 29 апреля 2009

Асинхронным шаблоном является BeginRead () / EndRead ().

Получите ли вы повышение, во многом зависит от того, что еще происходит во время чтения. Есть ли что-то еще, что может сделать ваше приложение во время ожидания чтения? Если нет, то асинхронность не сильно поможет ...

0 голосов
/ 29 апреля 2009

Если производительность является сверхкритической, я бы порекомендовал изучить взаимодействие для FILE_FLAG_SEQUENTIAL_SCAN См. подробности здесь

Лучше по-прежнему написать крошечное приложение на C ++, которое просматривает файл с этим флагом, чтобы узнать, не улучшает ли оно производительность.

...