/// <summary>Initializes the debug view.</summary> /// <param name="actionBlock">The target being debugged.</param> public DebugView(ActionBlock <TInput> actionBlock) { Contract.Requires(actionBlock != null, "Need a block with which to construct the debug view."); _actionBlock = actionBlock; if (_actionBlock._defaultTarget != null) { _defaultDebugInfo = actionBlock._defaultTarget.GetDebuggingInformation(); } else { _spscDebugInfo = actionBlock._spscTarget.GetDebuggingInformation(); } }
/// <summary>Initializes the <see cref="ActionBlock{T}"/> with the specified delegate and options.</summary> /// <param name="action">The action to invoke with each data element received.</param> /// <param name="dataflowBlockOptions">The options with which to configure this <see cref="ActionBlock{T}"/>.</param> /// <exception cref="System.ArgumentNullException">The <paramref name="action"/> is null (Nothing in Visual Basic).</exception> /// <exception cref="System.ArgumentNullException">The <paramref name="dataflowBlockOptions"/> is null (Nothing in Visual Basic).</exception> private ActionBlock(Delegate action, ExecutionDataflowBlockOptions dataflowBlockOptions) { // Validate arguments if (action == null) { throw new ArgumentNullException("action"); } if (dataflowBlockOptions == null) { throw new ArgumentNullException("dataflowBlockOptions"); } Contract.Ensures((_spscTarget != null) ^ (_defaultTarget != null), "One and only one of the two targets must be non-null after construction"); Contract.EndContractBlock(); // Ensure we have options that can't be changed by the caller dataflowBlockOptions = dataflowBlockOptions.DefaultOrClone(); // Based on the mode, initialize the target. If the user specifies SingleProducerConstrained, // we'll try to employ an optimized mode under a limited set of circumstances. var syncAction = action as Action <TInput>; if (syncAction != null && dataflowBlockOptions.SingleProducerConstrained && dataflowBlockOptions.MaxDegreeOfParallelism == 1 && !dataflowBlockOptions.CancellationToken.CanBeCanceled && dataflowBlockOptions.BoundedCapacity == DataflowBlockOptions.Unbounded) { // Initialize the SPSC fast target to handle the bulk of the processing. // The SpscTargetCore is only supported when BoundedCapacity, CancellationToken, // and MaxDOP are all their default values. It's also only supported for sync // delegates and not for async delegates. _spscTarget = new SpscTargetCore <TInput>(this, syncAction, dataflowBlockOptions); } else { // Initialize the TargetCore which handles the bulk of the processing. // The default target core can handle all options and delegate flavors. if (syncAction != null) // sync { _defaultTarget = new TargetCore <TInput>(this, messageWithId => ProcessMessage(syncAction, messageWithId), null, dataflowBlockOptions, TargetCoreOptions.RepresentsBlockCompletion); } else // async { var asyncAction = action as Func <TInput, Task>; Debug.Assert(asyncAction != null, "action is of incorrect delegate type"); _defaultTarget = new TargetCore <TInput>(this, messageWithId => ProcessMessageWithTask(asyncAction, messageWithId), null, dataflowBlockOptions, TargetCoreOptions.RepresentsBlockCompletion | TargetCoreOptions.UsesAsyncCompletion); } // Handle async cancellation requests by declining on the target Common.WireCancellationToComplete( dataflowBlockOptions.CancellationToken, Completion, state => ((TargetCore <TInput>)state).Complete(exception: null, dropPendingMessages: true), _defaultTarget); } #if FEATURE_TRACING DataflowEtwProvider etwLog = DataflowEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.DataflowBlockCreated(this, dataflowBlockOptions); } #endif }