【发布时间】:2015-09-08 18:23:02
【问题描述】:
我有一个TransformManyBlock,其设计如下:
- 输入:文件路径
- 输出:文件内容的 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:我没时间在这里和你争论——祝你好运
-
如果您仔细阅读该部分的其余部分,您会发现它并没有像您想象的那样工作 - 您的
firstBlock总是提供它可以产生的一切 - 如果您绑定第二个它只会拒绝第二个输入并稍后获取它
标签: c# .net task-parallel-library dataflow tpl-dataflow