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); }
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); }