7

我正在使用带有> 的生产者/消费者模式System.Collection.Concurrent.BlockingCollection<DataTable从数据库(生产者)中检索数据并在数据(消费者)上创建一个 Lucene 索引。

Producer 一次抓取 10000 条记录并将集合添加到BlockingCollection<DataTable>. 消费者(稍微慢一点)然后抓取这 10000 个并创建一个索引。

阻塞集合限制为<DataTable>10000 行中的 5 行。

起初,该程序运行良好,但在它获得大约 150000 行后,我注意到我的计算机内存已用完并且速度变慢。

似乎 BlockingCollectionnull在获取项目后无法将基础数组槽设置为。

代码:

    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 回答