我使用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