Чтение нескольких потоков из одного файла - PullRequest
14 голосов
/ 20 августа 2010

У меня есть XML-файл, который нужно читать много раз.Я пытаюсь использовать Parallel.ForEach для ускорения этого процесса, поскольку ни одна из данных, которые считываются, не имеет отношения к тому, в каком порядке они читаются. Данные просто используются для заполнения объектов.Моя проблема в том, что я открываю файл каждый раз в ветке, так как только для чтения он жалуется на то, что он открыт другой программой.(У меня нет его в текстовом редакторе или в любом другом виде :))

Как мне выполнить многократное чтение из одного и того же файла?

РЕДАКТИРОВАТЬ: Файл ~ 18 КБ довольно маленький.Читается примерно с 1800 раз.

Спасибо

Ответы [ 3 ]

31 голосов
/ 20 августа 2010

Если вы хотите, чтобы несколько потоков читали из одного и того же файла, вам необходимо указать FileShare.Read:

using (var stream = File.Open("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    ...
}

Тем не менее, вы не добьетесь ускорения по нескольким причинам:

  1. Ваш жесткий диск может читать только одну вещь за раз. Хотя у вас одновременно запущено несколько потоков, все эти потоки в конечном итоге будут ждать друг друга.
  2. Вы не можете легко разобрать часть файла XML. Обычно вам придется каждый раз анализировать весь XML-файл. Поскольку у вас есть несколько потоков, читающих это все время, кажется, что вы не ожидаете, что файл изменится. Если это так, то зачем вам читать его несколько раз?
3 голосов
/ 20 августа 2010

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

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

Общая предпосылка заключается в том, чтобы загрузить файл один раз в один поток, а затем либо напрямую (через структуру Xml) или косвенно (через XmlNodes и т. д.) предоставляют доступ к файлу каждому из ваших потоков.Я предполагаю что-то похожее на:

  1. Загрузить файл
  2. Для каждого запроса Xpath отправьте соответствующие узлы в ваши потоки.

Если потоки не изменяютсянапрямую XML, это может быть жизнеспособной альтернативой.

1 голос
/ 20 августа 2010

Когда вы открываете файл, вам нужно указать FileShare.Read:

using (var stream = new FileStream("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    ...
}

Таким образом, файл можно открыть несколько раз для чтения

...