У меня есть TransformManyBlock
со следующим дизайном:
- Ввод: путь к файлу
- Вывод: IEnumerable содержимого файла, по одной строке за раз
Я запускаю этот блок в огромном файле (61 ГБ), который слишком велик, чтобы поместиться в ОЗУ. Чтобы избежать неограниченного роста памяти, я установил 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-разрядную систему, обязательно снимите флажок «Предпочитать 32-разрядную версию» в Visual Studio. У меня на компе 16гб ОЗУ, и эта программа сразу потребляет каждый доступный байт.
firstBlock
всегда предлагает все, что может произвести - если вы привяжете второй, он просто отклонит второй ввод и получит его позже - person Random Dev   schedule 23.06.2015