我有以下的設計TransformManyBlock
:TPL數據流塊消耗所有可用內存
- 輸入:文件路徑
- 輸出:將IEnumerable的文件的內容,一條線在同一時間
我在一個龐大的文件(61GB)上運行這個塊,這個文件太大而不適合RAM。爲了避免無限制的內存增長,我已經將BoundedCapacity
設置爲該塊的非常低的值(例如1)以及所有的下游塊。儘管如此,該塊顯然重複IEnumerable貪婪,這消耗了計算機上的所有可用內存,使每個進程停止。該塊的OutputCount繼續無限制地上升,直到我終止進程。
我該怎麼做才能防止塊以這種方式使用IEnumerable
?
編輯:這裏是一個能說明問題的例子程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
class Program
{
static IEnumerable<string> GetSequence(char c)
{
for (var i = 0; i < 1024 * 1024; ++i)
yield return new string(c, 1024 * 1024);
}
static void Main(string[] args)
{
var options = new ExecutionDataflowBlockOptions() { BoundedCapacity = 1 };
var firstBlock = new TransformManyBlock<char, string>(c => GetSequence(c), options);
var secondBlock = new ActionBlock<string>(str =>
{
Console.WriteLine(str.Substring(0, 10));
Thread.Sleep(1000);
}, options);
firstBlock.LinkTo(secondBlock);
firstBlock.Completion.ContinueWith(task =>
{
if (task.IsFaulted) ((IDataflowBlock) secondBlock).Fault(task.Exception);
else secondBlock.Complete();
});
firstBlock.Post('A');
firstBlock.Complete();
for (; ;)
{
Console.WriteLine("OutputCount: {0}", firstBlock.OutputCount);
Thread.Sleep(3000);
}
}
}
如果您使用的是64位中,確保清除在Visual Studio中的「首選32位」選項。我的計算機上有16GB的RAM,並且該程序立即消耗了所有可用的字節。
以及TBH:我沒有時間在這裏與你爭辯 - 祝你好運 – Carsten
好的,謝謝你的反饋。 – brianberns
如果仔細閱讀了本節的其餘部分,您會發現它並不像您想象的那樣工作 - 您的firstBlock總是提供它可以生成的所有內容 - 如果您綁定了第二個,它將會拒絕第二個輸入並在稍後獲取它 – Carsten