} // proc StartJob public Task ExecuteJobAsync(ICronJobExecute job, CancellationToken cancellation) { using (currentJobs.EnterWriteLock()) { if (currentJobs.FindIndex(c => job == c.Job) >= 0) { throw new InvalidOperationException("Job is already running."); } using (currentJobs.EnterReadLock()) { foreach (var j in currentJobs) { if (!job.CanRunParallelTo(j.Job)) { throw new InvalidOperationException(String.Format("Job is blocked (job: {0})", j.Job.DisplayName)); } } } Log.Info("jobstart: {0}", job.DisplayName); var currentJob = new CurrentRunningJob(this, job, cancellation); currentJobs.Add(currentJob); return(currentJob.Task); } } // func ExecuteJobAsync
} // proc CronIdle public bool StartJob(ICronJobExecute job) { // is the job currently running try { ExecuteJobAsync(job, CancellationToken.None); return(true); } catch (InvalidOperationException) { return(false); } } // proc StartJob
public CurrentRunningJob(DECronEngine parent, ICronJobExecute job, CancellationToken cancellationToken) { this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); this.job = job ?? throw new ArgumentNullException(nameof(job)); this.jobCancel = job as ICronJobCancellation; this.cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); this.task = Task.Factory.StartNew(Execute, cancellationTokenSource.Token); this.task.ContinueWith(EndExecute); // automatic cancel if (jobCancel != null && jobCancel.RunTimeSlice.HasValue) { cancellationTokenSource.CancelAfter(jobCancel.RunTimeSlice.Value); } } // ctor
} // proc FinishJob public void CancelJob(ICronJobExecute job) { Task t = null; using (currentJobs.EnterReadLock()) { var cur = currentJobs.FirstOrDefault(c => c.Job == job); if (cur != null) { t = cur.Task; cur.Cancel(); } } try { t.Wait(); } catch { } } // proc CancelJob
} // proc ICronJobExecute.RunJob bool ICronJobExecute.CanRunParallelTo(ICronJobExecute other) { if (other == this) // do not run parallel the same job { return(false); } if (runAfterJob == null) { return(true); } else { return(!(other is ICronJobItem o) || runAfterJob.FirstOrDefault(c => Procs.IsFilterEqual(o.UniqueName, c)) == null || CanRunParallelTo(o)); } } // func ICronJobExecute.CanRunParallelTo
/// <summary>Execute more than one job.</summary> /// <param name="job"></param> protected async Task ExecuteJobAsync(ICronJobExecute job, CancellationToken cancellation) { CheckCronEngine(); await CronEngine.ExecuteJobAsync(job, cancellation); } // proc ExecuteJobAsync