> を含むプロデューサー/コンシューマー パターンを使用System.Collection.Concurrent.BlockingCollection<DataTable
して、データベース (プロデューサー) からデータを取得し、データ (コンシューマー) に Lucene インデックスを作成します。
Producer は一度に 10000 レコードを取得し、セットを に追加しBlockingCollection<DataTable>
ます。コンシューマー (少し遅い) は、それらの 10000 を取得してインデックスを作成します。
ブロッキング コレクションは、<DataTable>
それぞれ 10000 行中 5 行に制限されています。
最初はプログラムはうまく動作しますが、約 150000 行を取得した後、コンピューターのメモリが使い果たされ、速度が遅くなることに気付きました。
null
アイテムが取得された後、BlockingCollection が基になる配列スロットを設定できないようです。
コード:
private static LuceneIndex index;
private static BlockingCollection<DataTable> blockingCol;
private static void Producer()
{
while (true)
{
//...get next 10000 rows
DataTable data = GetNextSet();
if(data.Row.Count > 0)
blockingCol.Add(products);
else
break;
}
}
private static void Consumer()
{
while (!BlockingCol.IsCompleted || BlockingCol.Count > 0)
{
DataTable data = blockingCol.Take();
index.UpdateIndex(GetLuceneDocs(data));
}
}
public static void Main(System.String[] args)
{
index = new LuceneIndex();
blockingCol = new BlockingCollection<DataTable>(2);
// Create the producer and consumer tasks.
Task Prod = new Task(Producer);
Task Con = new Task(Consumer);
// Start the tasks.
Con.Start();
Prod.Start();
// Wait for both to finish.
try
{
Task.WaitAll(Con, Prod);
}
catch (AggregateException exc)
{
Console.WriteLine(exc);
}
finally
{
Con.Dispose();
Prod.Dispose();
blockingCol.Dispose();
}
}
この一時停止を拒否したことを確認できる人はいますか? 回避策はありますか?