1

私が構築しているアプリケーションは、あるソースからログを読み取り、それをグリッドに表示します。ログのサイズは数MBから数GBです。メモリの問題を防ぐために、グリッドを使用して、一度に500行ずつログをページングしています。これが私がやりたいことです:

ログを読み取り、毎回約500行のファイルに書き込むスレッドを作成してから、ログが書き込まれたことを別のスレッドに通知したいと思います。次に、他のスレッドがファイルを読み取り、グリッドに行を表示して、最初のスレッドに読み取りが終了したことを通知します。これは、ファイルに書き込まれるログがなくなるまで続きます。

このようにスレッドを切り替えることは可能ですか?

4

2 に答える 2

2

はい、もちろん、これは生産者と消費者のモデルのバリエーションです。

Threadここでは、 やのようないくつかの基本的なビルディング ブロックを使用できますAutoResetEvent。「プロデューサー」はログから行を読み取り、それらをファイルに投稿し (代わりにメモリ内バッファーを使用できますか?)、他のスレッドにそれらを読み取るように通知します。

AutoResetEvent consumerEvent = new AutoResetEvent(false);
AutoResetEvent producerEvent = new AutoResetEvent(false);

// producer code
while(/* lines still available */)
{
    // read 500 lines
    // write to shared file
    consumerEvent.Set(); // signal consumer thread
    producerEvent.WaitOne(); // wait to be signaled to continue
}

そして消費者コード:

while(/* termination not received */)
{
    consumerEvent.WaitOne(); // wait for the producer to finish     
    // read lines from file and put them in the grid
    producerEvent.Set(); // allow producer to read more logs
}

これにより、ファイルを読み取るコンシューマーと、さらにログを読み取り、次のバッチを準備するプロデューサーとの間で、ある程度の並列処理が可能になります。

プロデューサーがログの処理を終了すると、ファイルに特別な終了メッセージを入れて、正常に終了するようにコンシューマーに通知できます。

これは 1 つの戦略であり、かなり低レベルでエラーが発生しやすいものです。共有ファイルを完全にスキップして、BlockingCollectionの形式でメモリ内バッファを使用できます。

ProducerTask数行のテキストを保持するクラスを定義します。

class ProducerTask 
{
    public String[] Lines { get; set; }
}

このタスクは一度に 500 行を保持します。

次に、次のようTaskに and BlockingCollection(.NET 4.0+) を使用します。

BlockingCollection<ProducerTask> buffer = new BlockingCollection<ProducerTask>(1);

// producer task
while(/* lines still available */)
{
    // read 500 lines
    ProducerTask p = new ProducerTask();
    buffer.Add(p); // this will block until the consumer takes the previous task
}

// consumer task
while(/* termination not received */)
{
    ProducerTask p = buffer.Take(); // blocks if no task is available
    // put the lines in the grid
}

はるかにシンプルでエレガント。

于 2012-06-01T11:58:05.533 に答える
0

Tudor の非常に優れた回答に続いて、TPL Dataflowも参照できます。TPL Dataflowは、生産者と消費者のパターンを実装するための非常にクリーンなビルディング ブロックのセットを提供します。

于 2012-06-01T12:54:08.547 に答える