Я бы построил такой блок из BufferBlock<T>
: метод принимает делегат, который представляет сторону блока ITargetBlock<T>
и возвращает его сторону ISourceBlock<T>
. Таким образом, делегат может отправлять входные данные блоку, но извне он выглядит как блок, который только производит вывод.
Код:
public static ISourceBlock<T> CreateProducerBlock<T>(
Func<ITargetBlock<T>, Task> producer,
int boundedCapacity = DataflowBlockOptions.Unbounded)
{
var block = new BufferBlock<T>(
new ExecutionDataflowBlockOptions { BoundedCapacity = boundedCapacity });
Task.Run(async() =>
{
try
{
await producer(block);
block.Complete();
}
catch (Exception ex)
{
((IDataflowBlock)block).Fault(ex);
}
});
return block;
}
Пример использования:
var producer = CreateProducerBlock<int>(async target =>
{
await target.SendAsync(10);
await target.SendAsync(20);
});
ITargetBlock<int> consumer = …;
producer.LinkTo(consumer);
No. Зачем вам это нужно тоже? Может быть, мы сможем создать что-то подобное. – i3arnon
Мой первый блок извлекает данные из очереди. Для ввода данных из очереди не требуется никакого ввода. –
@BilalFazlani на самом деле, у него есть вход. Сама очередь. TransformManyBlock может принимать очередь в качестве входных данных и возвращать ее содержимое в качестве вывода. Или вы можете заменить свою очередь BufferBlock (которая также является очередью). Или вы можете просто использовать цикл, который выводит сообщения из очереди и отправляет их в первый блок –