コンパイラ、オプティマイザ、およびインデックス作成テクノロジについて詳しく知るために、C#でおもちゃのデータベースを構築しています。
ページをバッファプールに取り込むための(少なくとも読み取り)要求間で最大の並列処理を維持したいのですが、.NETでこれを実現するための最善の方法について混乱しています。
ここにいくつかのオプションと私がそれぞれに遭遇した問題があります:
使用法
System.IO.FileStream
とBeginRead
方法ただし、ファイル内の位置はの引数ではなく、(メソッドを介して設定された)
BeginRead
のプロパティであるため、一度に1つのリクエストしか発行できず、その間ストリームをロックする必要があります。(または、私は?との間にのみロックを保持し、電話をかける前にロックを解除した場合、ドキュメントは不明確です。誰か知っていますか?)これを行う方法を知っていますが、それが最良の方法。FileStream
Seek
Seek
BeginRead
EndRead
構造とkernel32.dll
System.Threading.Overlapped
の関数へのP\Invokeを 中心とした別の方法があるようです。ReadFileEx
残念ながら、特に管理された言語では、サンプルが不足しています。このルート(動作させることができる場合)には
ThreadPool.BindHandle
、スレッドプール内のメソッドとIO完了スレッドも含まれているようです。これがウィンドウの下でこのシナリオを処理するための認可された方法であるという印象を受けますが、私はそれを理解しておらず、初心者に役立つドキュメントへのエントリポイントを見つけることができません。他に何かありますか?
コメントの中で、jacobは
FileStream
、飛行中の読み取りごとに新しいものを作成することを提案しています。ファイル全体をメモリに読み込みます。
これは、データベースが小さい場合に機能します。コードベースは小さく、他にも多くの非効率性がありますが、データベース自体はそうではありません。また、大規模なデータベース(ページング、外部ソーティングなど、複雑さの大部分を占めることが判明)を処理するために必要なすべての簿記を確実に実行していることを確認したいと思います。誤ってごまかしやすい。
編集
解決策1に疑問がある理由の明確化:BeginReadからEndReadまでずっと単一のロックを保持するということは、別の読み取りが進行中であるという理由だけで読み取りを開始したい人をブロックする必要があることを意味します。新しい読み取りを開始するスレッドは、結果が利用可能になる前に(一般に)さらにいくつかの作業を実行できる可能性があるため、これは間違っていると感じます。(実際、これを書くだけで、新しい解決策を考えるようになりました。私は新しい答えとして置きました。)