2017-03-23 3 views

답변

1

BatchBlock 뒤에 BroadcastBlock이 필요합니다. 그러나 완료는 귀하의 TransformBlock 중 하나로 만 전파됩니다. 일부 예 완료를 처리하기 위해 아래를 참조하십시오 : 파이프 라인은 결코 수렴하지 않는 경우

using System.Threading.Tasks.Dataflow; 

namespace MyDataflow { 
    class MyDataflow { 

     public void HandlingCompletion() { 
      var batchBlock = new BatchBlock<int>(10); 
      var broadcastBlock = new BroadcastBlock<int[]>(_ => _); 
      var xForm1 = new TransformBlock<int[], int[]>(_ => _); 
      var xForm2 = new TransformBlock<int[], int[]>(_ => _); 

      batchBlock.LinkTo(broadcastBlock, new DataflowLinkOptions() { PropagateCompletion = true }); 
      broadcastBlock.LinkTo(xForm1); 
      broadcastBlock.LinkTo(xForm1); 

      broadcastBlock.Completion.ContinueWith(broadcastBlockCompletionTask => { 
       if (!broadcastBlockCompletionTask.IsFaulted) { 
        xForm1.Complete(); 
        xForm2.Complete(); 
       }else { 
        ((IDataflowBlock)xForm1).Fault(broadcastBlockCompletionTask.Exception); 
        ((IDataflowBlock)xForm2).Fault(broadcastBlockCompletionTask.Exception); 
       } 

      }); 

      xForm1.Completion.ContinueWith(async _ => { 
       try { 
        await xForm2.Completion; 
        //continue passing completion/fault on to rest of pipeline 
       } catch { 

       } 
      }); 

     } 
    } 
} 

또한, 다시는 BroacastBlock을 계속 한 후 각각의 파이프 라인에 대해 개별적으로 완료를 처리 할 수 ​​있습니다. 제공된 예는 동시에 파이프 라인의 각 단계를 완료하고 동기를 따라 완료를 완료합니다. 두 번째 블록은 모든 메시지를하지 않는 이유 TPL 데이터 흐름에 연결 기본적으로

1

이, 욕심 고려, 그래서 첫 번째 대상은 항상 메시지 를 얻을 이전 블록 '출력에서 제거, 즉이다. 이러한 상황은

현재 요소가 요소가 덮어 쓸 수 있도록 전에 연결 대상에 방송되는 것을 보장하는 BroadcastBlock<T>에 의해 해결 될 수있다.

또한이 블록 은 메시지을 복제해야합니다.

기본적으로 배치 블록 뒤에 방송을 추가해야하지만! 방송 블록에서 소비자에게 완성을 전파해서는 안됩니다. 첫 번째 완성 만 완료됩니다. @JSteward가 제안한대로 방송용으로 ContinueWith 처리기를 추가해야합니다.