예제 #1
0
 /// <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();
     }
 }
예제 #2
0
        /// <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
        }