2

В названии моего вопроса говорится все.Есть ли блок потока данных TPL, который не принимает ввода, а возвращает выход?

Я ищу блок потока данных TPL, который не требует ввода.

Прямо сейчас я использую блок преобразования, но его ввод не используется.

+0

No. Зачем вам это нужно тоже? Может быть, мы сможем создать что-то подобное. – i3arnon

+0

Мой первый блок извлекает данные из очереди. Для ввода данных из очереди не требуется никакого ввода. –

+0

@BilalFazlani на самом деле, у него есть вход. Сама очередь. TransformManyBlock может принимать очередь в качестве входных данных и возвращать ее содержимое в качестве вывода. Или вы можете заменить свою очередь BufferBlock (которая также является очередью). Или вы можете просто использовать цикл, который выводит сообщения из очереди и отправляет их в первый блок –

ответ

3

Я бы построил такой блок из 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); 
+0

Я искал пример реализации ISourceBlock , но это просто и элегантно! – Guge