public async Task HandleAsync(CommandContext context, NextDelegate next) { if (context.Command is BulkUpdateAssets bulkUpdates) { if (bulkUpdates.Jobs?.Length > 0) { var executionOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Math.Max(1, Environment.ProcessorCount / 2) }; var createCommandsBlock = new TransformBlock <BulkTask, BulkTaskCommand?>(task => { try { return(CreateCommand(task)); } catch (OperationCanceledException ex) { // Dataflow swallows operation cancelled exception. throw new AggregateException(ex); } }, executionOptions); var executeCommandBlock = new ActionBlock <BulkTaskCommand?>(async command => { try { if (command != null) { await ExecuteCommandAsync(command); } } catch (OperationCanceledException ex) { // Dataflow swallows operation cancelled exception. throw new AggregateException(ex); } }, executionOptions); createCommandsBlock.BidirectionalLinkTo(executeCommandBlock); contextProvider.Context.Change(b => b .WithoutAssetEnrichment() .WithoutCleanup() .WithUnpublished(true) .WithoutTotal()); var results = new ConcurrentBag <BulkUpdateResultItem>(); for (var i = 0; i < bulkUpdates.Jobs.Length; i++) { var task = new BulkTask( context.CommandBus, i, bulkUpdates.Jobs[i], bulkUpdates, results); if (!await createCommandsBlock.SendAsync(task)) { break; } } createCommandsBlock.Complete(); await executeCommandBlock.Completion; context.Complete(new BulkUpdateResult(results)); } else { context.Complete(new BulkUpdateResult()); } } else { await next(context); } }