title: How to implement continuously running dataflow blocks in TPL?
body: <p>I have producer/consumer dataflow block set-up using BufferBlock and ActionBlock and it is working fine inside Console application; </p>
  
  <p>After adding all items into BurfferBlock and Linking BufferBlock with other Action Items; it is working good. </p>
  
  <p>now I want to use that inside service where this dataflow block pipeline will always be up and and when messages will be available through external events it would go inside bufferblock and that will start processing. How can I achieve this?</p>
  
  <p>So far I have done below:</p>
  
  <pre><code>public void SetupPipeline()
  {
      FirstBlock = new ActionBlock&lt;WorkItem&gt;(new Action&lt;WorkItem&gt;(ProcessIncomingMessage),
      new ExecutionDataflowBlockOptions
      {
          MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
      });
  
      BufferBlock = new BufferBlock&lt;WorkItem&gt;();
  
      GroupingDataflowBlockOptions GroupingDataflowBlockOptions = new GroupingDataflowBlockOptions();
      GroupingDataflowBlockOptions.Greedy = true;
      GroupingDataflowBlockOptions.BoundedCapacity = GroupingDataflowBlockOptions.Unbounded;
      CancellationTokenSource = new CancellationTokenSource();
      CancellationToken = CancellationTokenSource.Token;
      GroupingDataflowBlockOptions.CancellationToken = CancellationToken;
      BatchBlock = new BatchBlock&lt;WorkItem&gt;(BoundingCapacity, GroupingDataflowBlockOptions);
  
      ProcessItems = new ActionBlock&lt;WorkItem[]&gt;(WorkItems =&gt;
          ProcessWorkItems(WorkItems.ToList&lt;WorkItem&gt;()),
          new ExecutionDataflowBlockOptions
        {
            CancellationToken = CancellationToken
        });
  
      Timer = new Timer(_ =&gt;
              BatchBlock.TriggerBatch()
          );
  
      TimingBlock = new TransformBlock&lt;WorkItem, WorkItem&gt;(WorkItem =&gt;
      {
          Timer.Change(TimerInterval, Timeout.Infinite);
          logger.Debug("Inside TimingBlock : " + WorkItem.ToString());
          return WorkItem;
      }, new ExecutionDataflowBlockOptions
      {
          CancellationToken = CancellationToken
      });
  
      BatchBlock.LinkTo(ProcessItems);
      TimingBlock.LinkTo(BatchBlock);
      BufferBlock.LinkTo(TimingBlock);
  }
  </code></pre>