public static void ExecuteTestPipelineStepOperation(string inputDirectory, string BackgroundFilePath, string outputdir, CancellationToken token) { var buffer1 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer2ForNormalTask1 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer2ForThumbnailTask1 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer2ForNormalTask2 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer2ForThumbnailTask2 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer3ForNormal = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer3ForThumbnail = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); var buffer4 = new BlockingCollection <BitmapWithFilePathAndSeq>(BUFFER_SIZE); Bitmap background_bm = ImageProcessor.LoadFileAsImage(BackgroundFilePath); using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(token)) { var f = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); List <TaskPipelineStep <BitmapWithFilePathAndSeq> > pipelineSteps = new List <TaskPipelineStep <BitmapWithFilePathAndSeq> >(); // FIRST TASK var pipelineStep1Task = new PipeLineStep <BitmapWithFilePathAndSeq, BitmapWithFilePathAndSeq>( null, ( BlockingCollection <BitmapWithFilePathAndSeq> inputQ, BlockingCollection <BitmapWithFilePathAndSeq> outputQ, CancellationToken suspend, CancellationTokenSource cancel ) => LoadImages(inputDirectory, outputQ, cancel), cts, buffer1 ).Start(); // SECOND TASK var pipelineStep2 = new PipeLineStep <BitmapWithFilePathAndSeq, BitmapWithFilePathAndSeq>( buffer1, ( BlockingCollection <BitmapWithFilePathAndSeq> inputQ, BlockingCollection <BitmapWithFilePathAndSeq> outputQ, CancellationToken suspend, CancellationTokenSource cancel ) => RemoveBackground(inputQ, background_bm, cts, suspend, outputQ), cts, buffer3ForThumbnail, buffer3ForNormal ); Task pipelineStep2Task = pipelineStep2.Start(); pipelineSteps.Add(new TaskPipelineStep <BitmapWithFilePathAndSeq>() { Name = "Step 2", PipelineStep = pipelineStep2, Tasks = new List <Task>() { pipelineStep2Task, pipelineStep2.MultiplexorTask }, Queue = buffer1, }); // THIRD TASKs var pipelineStep3 = new PipeLineStep <BitmapWithFilePathAndSeq, BitmapWithFilePathAndSeq>( buffer3ForThumbnail, ( BlockingCollection <BitmapWithFilePathAndSeq> inputQ, BlockingCollection <BitmapWithFilePathAndSeq> outputQ, CancellationToken suspend, CancellationTokenSource cancel ) => CreateThumbnail(inputQ, outputQ, cancel), cts, buffer4 ); Task pipelineStep3Task = pipelineStep3.Start(); pipelineSteps.Add(new TaskPipelineStep <BitmapWithFilePathAndSeq>() { Name = "Step 3", PipelineStep = pipelineStep3, Tasks = new List <Task>() { pipelineStep3Task, pipelineStep3.MultiplexorTask }, Queue = buffer3ForThumbnail, }); var stage3Normal = f.StartNew(() => SaveBitmap(buffer3ForNormal, outputdir, cts)); // FOURTH TASK var stage4 = f.StartNew(() => SaveThumbnailBitmap(buffer4, outputdir, cts)); try { DistributeAvailableTasksAndAwaitPipelineCompletion(new List <Task>() { pipelineStep1Task, stage3Normal, stage4 }, pipelineSteps); } catch (Exception ex) { if (ex is AggregateException ae) // Unwrap aggregate exception. { ae.Handle((ie) => { throw ie; }); } throw ex; } } }