Пример #1
0
        internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
        {
            if (childJob == null)
            {
                throw new ArgumentNullException("childJob");
            }
            if (childJob.JobStateInfo.State != JobState.NotStarted)
            {
                throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, "childJob");
            }
            base.AssertNotDisposed();
            JobStateInfo info = null;

            lock (this._lockObject)
            {
                if (this.IsEndOfChildJobs)
                {
                    throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
                }
                if (this._isStopping)
                {
                    return;
                }
                if (this._countOfAllChildJobs == 0)
                {
                    info = new JobStateInfo(JobState.Running);
                }
                if (ChildJobFlags.CreatesChildJobs == (ChildJobFlags.CreatesChildJobs & flags))
                {
                    this._setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
                }
                base.ChildJobs.Add(childJob);
                this._childJobLocations.Add(childJob.Location);
                this._countOfAllChildJobs++;
                this.WriteWarningAboutHighUsageOfFlowControlBuffers((long)this.CountOfRunningOrReadyToRunChildJobs);
                if (this.CountOfRunningOrReadyToRunChildJobs > this._maxReadyToRunJobs)
                {
                    this._actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
                }
                else if (jobEnqueuedAction != null)
                {
                    jobEnqueuedAction();
                }
            }
            if (info != null)
            {
                base.SetJobState(info.State, info.Reason);
            }
            this.ChildJobAdded.SafeInvoke <ThrottlingJobChildAddedEventArgs>(this, new ThrottlingJobChildAddedEventArgs(childJob));
            childJob.SetParentActivityIdGetter(new Func <int>(this.GetProgressActivityId));
            childJob.StateChanged += new EventHandler <JobStateEventArgs>(this.childJob_StateChanged);
            if (this._cmdletMode)
            {
                childJob.Results.DataAdded += new EventHandler <DataAddedEventArgs>(this.childJob_ResultsAdded);
            }
            this.EnqueueReadyToRunChildJob(childJob);
            this.ReportProgress(true);
        }
        /// <summary>
        /// Adds and starts a child job.
        /// </summary>
        /// <param name="childJob">Child job to add.</param>
        /// <param name="flags">Flags of the child job.</param>
        /// <param name="jobEnqueuedAction">Action to run after enqueuing the job.</param>
        /// <exception cref="ArgumentException">
        /// Thrown when the child job is not in the <see cref="JobState.NotStarted"/> state.
        /// (because this can lead to race conditions - the child job can finish before the parent job has a chance to register for child job events)
        /// </exception>
        internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
        {
            if (childJob == null)
            {
                throw new ArgumentNullException(nameof(childJob));
            }
            if (childJob.JobStateInfo.State != JobState.NotStarted)
            {
                throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, nameof(childJob));
            }
            this.AssertNotDisposed();

            JobStateInfo newJobStateInfo = null;

            lock (_lockObject)
            {
                if (this.IsEndOfChildJobs)
                {
                    throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
                }
                if (_isStopping)
                {
                    return;
                }

                if (_countOfAllChildJobs == 0)
                {
                    newJobStateInfo = new JobStateInfo(JobState.Running);
                }

                if ((ChildJobFlags.CreatesChildJobs & flags) == ChildJobFlags.CreatesChildJobs)
                {
                    _setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
                }

                this.ChildJobs.Add(childJob);
                _childJobLocations.Add(childJob.Location);
                _countOfAllChildJobs++;

                this.WriteWarningAboutHighUsageOfFlowControlBuffers(this.CountOfRunningOrReadyToRunChildJobs);
                if (this.CountOfRunningOrReadyToRunChildJobs > _maxReadyToRunJobs)
                {
                    _actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
                }
                else
                {
                    jobEnqueuedAction?.Invoke();
                }
            }

            if (newJobStateInfo != null)
            {
                this.SetJobState(newJobStateInfo.State, newJobStateInfo.Reason);
            }

            this.ChildJobAdded.SafeInvoke(this, new ThrottlingJobChildAddedEventArgs(childJob));

            childJob.SetParentActivityIdGetter(this.GetProgressActivityId);
            childJob.StateChanged += this.childJob_StateChanged;
            if (_cmdletMode)
            {
                childJob.Results.DataAdded += childJob_ResultsAdded;
            }

            this.EnqueueReadyToRunChildJob(childJob);

            this.ReportProgress(minimizeFrequentUpdates: true);
        }
Пример #3
0
 internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
 {
     if (childJob == null)
     {
         throw new ArgumentNullException("childJob");
     }
     if (childJob.JobStateInfo.State != JobState.NotStarted)
     {
         throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, "childJob");
     }
     base.AssertNotDisposed();
     JobStateInfo info = null;
     lock (this._lockObject)
     {
         if (this.IsEndOfChildJobs)
         {
             throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
         }
         if (this._isStopping)
         {
             return;
         }
         if (this._countOfAllChildJobs == 0)
         {
             info = new JobStateInfo(JobState.Running);
         }
         if (ChildJobFlags.CreatesChildJobs == (ChildJobFlags.CreatesChildJobs & flags))
         {
             this._setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
         }
         base.ChildJobs.Add(childJob);
         this._childJobLocations.Add(childJob.Location);
         this._countOfAllChildJobs++;
         this.WriteWarningAboutHighUsageOfFlowControlBuffers((long) this.CountOfRunningOrReadyToRunChildJobs);
         if (this.CountOfRunningOrReadyToRunChildJobs > this._maxReadyToRunJobs)
         {
             this._actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
         }
         else if (jobEnqueuedAction != null)
         {
             jobEnqueuedAction();
         }
     }
     if (info != null)
     {
         base.SetJobState(info.State, info.Reason);
     }
     this.ChildJobAdded.SafeInvoke<ThrottlingJobChildAddedEventArgs>(this, new ThrottlingJobChildAddedEventArgs(childJob));
     childJob.SetParentActivityIdGetter(new Func<int>(this.GetProgressActivityId));
     childJob.StateChanged += new EventHandler<JobStateEventArgs>(this.childJob_StateChanged);
     if (this._cmdletMode)
     {
         childJob.Results.DataAdded += new EventHandler<DataAddedEventArgs>(this.childJob_ResultsAdded);
     }
     this.EnqueueReadyToRunChildJob(childJob);
     this.ReportProgress(true);
 }