Чтение нескольких потоков из одного файла

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

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

EDIT: файл ~ 18KB довольно маленький. Он читается примерно в 1800 раз.

Спасибо

Ответ 1

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

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

Однако вы не сможете ускорить это по нескольким причинам:

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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