web-dev-qa-db-ja.com

同じファイルから読み取る複数のスレッド

何度も読み取る必要のあるxmlファイルがあります。 Parallel.ForEachを使用して、このプロセスを高速化しようとしています。これは、読み込まれるデータが、読み込まれる順序に関連していないためです。データは、オブジェクトの入力に使用されているだけです。私の問題は、スレッドで毎回ファイルを読み取り専用として開いているにもかかわらず、別のプログラムによって開かれていると文句を言うことです。 (私はそれをテキストエディタか何かで開いていません:))

同じファイルから複数の読み取りを実行するにはどうすればよいですか?

編集:ファイルは〜18KBかなり小さいです。約1800回から読まれています。

ありがとう

14
Pieces

同じファイルから複数のスレッドを読み取る場合は、FileShare.Readを指定する必要があります。

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

ただし、複数の理由により、これによるスピードアップは達成されません。

  1. ハードディスクは一度に1つのものしか読み取ることができません。複数のスレッドを同時に実行していますが、これらのスレッドはすべて互いに待機することになります。
  2. XMLファイルの一部を簡単に解析することはできません。通常、XMLファイル全体を毎回解析する必要があります。複数のスレッドが常にそれを読み取っているので、ファイルが変更されることを期待していないようです。もしそうなら、なぜあなたはそれを複数回読む必要があるのですか?
32
Timwi

ファイルのサイズと実行している読み取りのタイプによっては、最初にファイルをメモリにロードしてから、スレッドに直接アクセスできるようにする方が速い場合があります。

ファイルや読み取りなどの詳細を提供しなかったため、特定のニーズに対応できるかどうかはわかりません。

一般的な前提は、ファイルを1つのスレッドに一度ロードしてから、直接(Xml構造を介して)または間接的に(XmlNodesなどを介して)各スレッドにファイルへのアクセスを提供することです。私は次のようなものを想像しています:

  1. ファイルをロードします
  2. Xpathクエリごとに、一致するノードをスレッドにディスパッチします。

スレッドがXMLを直接変更しない場合、これは実行可能な代替手段である可能性があります。

3
GrayWizardx

ファイルを開くときは、FileShare.Readを指定する必要があります。

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

そうすれば、ファイルを複数回開いて読み取ることができます

2
Thomas Levesque