7

> を含むプロデューサー/コンシューマー パターンを使用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();
             }
}

この一時停止を拒否したことを確認できる人はいますか? 回避策はありますか?

4

1 に答える 1

8

はい、確認できます。あなたは .NET 4.5 を使用していませんね。そこで修正されるはずです(この回答の下のコメントはこれを確認しているようです)。

とにかく、 a の周りに自分でラッパーを書きDataTable、テーブルを使い終わったらそのラッパーをクリアしてください。これにより、GC の対象となります。ラッパーは早期に GC されませんが、小さいです。

class Wrapper<T> { public T Item; }
于 2012-10-10T17:02:13.343 に答える