private (ITargetBlock <string>, Task) CreatePipeline() { var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; TransformManyBlock <object, IImage> fetchBlock = new TransformManyBlock <object, IImage>(_ => _functions.Fetch(_options.Value.Location), new ExecutionDataflowBlockOptions { BoundedCapacity = 2, MaxDegreeOfParallelism = 1 }); TransformManyBlock <IImage, IImage> detectFacesBlock = new TransformManyBlock <IImage, IImage>(source => _functions.ExtractFaces(source)); TransformManyBlock <IImage, IRecognition> recogniseFacesBlock = new TransformManyBlock <IImage, IRecognition>(source => _functions.RecogniseFaces(source)); TransformBlock <IRecognition, IPersistedRecognition> persistRecognitionBlock = new TransformBlock <IRecognition, IPersistedRecognition>(recognition => _functions.PersistRecognition(recognition), new ExecutionDataflowBlockOptions { BoundedCapacity = 10, MaxDegreeOfParallelism = 1 }); ActionBlock <IPersistedRecognition> notifyRecognitionBlock = new ActionBlock <IPersistedRecognition>(recognition => _functions.NotifyRecognition(recognition), new ExecutionDataflowBlockOptions { BoundedCapacity = 10, MaxDegreeOfParallelism = 1 }); fetchBlock.LinkTo(detectFacesBlock, linkOptions); detectFacesBlock.LinkTo(recogniseFacesBlock, linkOptions); recogniseFacesBlock.LinkTo(persistRecognitionBlock, linkOptions); persistRecognitionBlock.LinkTo(notifyRecognitionBlock, linkOptions); return(fetchBlock, notifyRecognitionBlock.Completion); }