我使用Producer/Consumer Pattern和System.Collection.Concurrent.BlockingCollection<DataTable
>从数据库(生产者)检索数据并在数据(消费者)上创建Lucene索引。.Net并发BlockingCollection有内存泄漏?
制作人一次抓取10000条记录,并将集添加到BlockingCollection<DataTable>
。消费者(比较慢一点)然后抓住这10000个并创建一个索引。
阻塞集合的范围是每行10000个行的5个<DataTable>
。
起初该程序运行良好,但在获取大约150000行后,我注意到我的电脑内存已经超出,并且慢慢爬行。
看来,BlockingCollection无法在拍摄该项目后将底层阵列插槽设置为null
。
代码:
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();
}
}
能
拒绝这种悬挂的任何人证实?有什么解决办法吗?
我在.net 4.5上。我实际上使用亚音速收集而不是数据表。为了简单起见,我在这个例子中只包含了数据表。我会尝试你的解决方案。 – NSjonas
我想这是不固定的然后(可能我记得)。不过,我自己也看到了这个问题。 – usr
包装 wrapper = BlockingCol.Take(); //做东西 wrapper.Item = null;这是你的意思吗? –
NSjonas