public void AbortJobBatch(JJobType jobType, int pauseBeforeAbort = 1000) { try { if (jobType.JobBatchObject != null) { CancelAsyncJobBatch(jobType); Thread.Sleep(pauseBeforeAbort); // List <JRunningJob> jobs = new List <JRunningJob>(); jobs.AddRange(jobType.JobBatchRunningDict.Values);//copy for prevent deadlock foreach (var job in jobs) { AbortJob(job); } // if (jobType.JobBatchObject is AbortableBackgroundWorker) { AbortableBackgroundWorker backgroundWorker1 = (jobType.JobBatchObject as AbortableBackgroundWorker); if (backgroundWorker1.IsBusy == true) { backgroundWorker1.Abort(); backgroundWorker1.Dispose(); } } ResetJobBatch(jobType); JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.aborted); } } catch (Exception ex) { Log.LogError("Error aborting job: " + jobType.JJobTypeId, ex); } }
public void AbortJob(JRunningJob job, int pauseBeforeAbort = 1000) { try { if (job.JobObject != null) { CancelAsyncJob(job); Thread.Sleep(pauseBeforeAbort); if (job.JobObject is AbortableBackgroundWorker) { AbortableBackgroundWorker backgroundWorker1 = (job.JobObject as AbortableBackgroundWorker); if (backgroundWorker1.IsBusy == true) { backgroundWorker1.Abort(); backgroundWorker1.Dispose(); } } ResetJob(job); ComplateJob(job, RunningJobStageEnum.aborted); } } catch (Exception ex) { Log.LogError("Error aborting job: " + job.JRunningJobId, ex); } }
static private void ScheduleJobBackgroundLocal(JRunningJob job) { BackgroundWorker worker = new AbortableBackgroundWorker(); worker.WorkerSupportsCancellation = true; worker.WorkerReportsProgress = true; worker.DoWork += (sd, ew) => { BackgroundWorker wk = sd as BackgroundWorker; if (wk.CancellationPending) { ew.Cancel = true; return; } try { JobDoWorkEventArgs arg = new JobDoWorkEventArgs(); job.JobLog.Info("Job started " + job.Name); arg.StageResult = RunningJobResultEnum.ok; job.Stage = RunningJobStageEnum.running.ToString(); job.JJobType.JobBatchRunningDict.TryAdd(job.JRunningJobId, job); Dm.Instance.SaveObject(job); job.RunJob(arg); if (arg.StageResult == RunningJobResultEnum.ok) { ew.Result = RunningJobStageEnum.complated; } else if (arg.StageResult == RunningJobResultEnum.warning) { ew.Result = RunningJobStageEnum.warning; } else if (arg.StageResult == RunningJobResultEnum.error) { ew.Result = RunningJobStageEnum.error; } if (job.CancellationPending) { ew.Cancel = true; } } catch (Exception ex) { if (ex is System.Threading.ThreadAbortException) { job.JobLog.Warn("Job aborted"); } else { job.JobLog.Error("Job fatal error", ex); } ew.Result = RunningJobStageEnum.exception; JobManager.Instance.ComplateJob(job, RunningJobStageEnum.exception); } finally { ResetJob(job); } }; worker.RunWorkerCompleted += (sd, ek) => { if (ek.Cancelled == true) { job.JobLog.Debug("Job aborted"); JobManager.Instance.ComplateJob(job, RunningJobStageEnum.aborted); } else { if (RunningJobStageEnum.exception.Equals(ek.Result)) { //do nothing } else if (RunningJobStageEnum.warning.Equals(ek.Result)) { JobManager.Instance.ComplateJob(job, RunningJobStageEnum.warning); } else if (RunningJobStageEnum.error.Equals(ek.Result)) { JobManager.Instance.ComplateJob(job, RunningJobStageEnum.error); } else { JobManager.Instance.ComplateJob(job, RunningJobStageEnum.complated); } } }; worker.ProgressChanged += (sd, pc) => { localReportProgresJob(job, pc.ProgressPercentage); }; //run worker job.JobObject = worker; (job.JobObject as BackgroundWorker).RunWorkerAsync(); if (job.JJobType != null) { job.JJobType.LastRunDate = DateTimeOffset.Now; Dm.Instance.SaveObject(job.JJobType); } }
static public void StartProcessingJobBatch(JJobType jobType) { if (jobType.JobBatchObject != null) { throw new InvalidOperationException(); //todo } BackgroundWorker mainWorker = new AbortableBackgroundWorker(); mainWorker.WorkerSupportsCancellation = true; mainWorker.WorkerReportsProgress = true; mainWorker.DoWork += (sd, ew) => { BackgroundWorker wk = sd as BackgroundWorker; if (wk.CancellationPending) { ew.Cancel = true; return; } try { if (jobType.JobBatchQueueSemaphore == null) { //first start int maxTreadCount = 1; if (JobConcurrentTypeEnum.Cancel.ToString().Equals(jobType.ConcurrentType)) { maxTreadCount = 1; } else if (JobConcurrentTypeEnum.Wait.ToString().Equals(jobType.ConcurrentType)) { maxTreadCount = 1; } else if (JobConcurrentTypeEnum.Allow.ToString().Equals(jobType.ConcurrentType)) { maxTreadCount = jobType.MaxThreadCount; } jobType.JobBatchRunningDict.Clear(); jobType.JobBatchQueueSemaphore = new Semaphore(maxTreadCount, maxTreadCount); jobType.JobBatchLog.Debug("JobType Semaphore created maxTreadCount: " + maxTreadCount); jobType.JobBatchLastRunDate = DateTime.Now; jobType.JobBatchStage = RunningJobStageEnum.running.ToString(); Dm.Instance.SaveObject(jobType); } List <AutoResetEvent> endHandlers = new List <AutoResetEvent>(); int initialQueueCount = jobType.JobBatchQueueCount; int startedCount = 0; while (true) { if (wk.CancellationPending) { ew.Cancel = true; break; } if (jobType.JobBatchQueueCount == 0) { break; } jobType.JobBatchQueueSemaphore.WaitOne(); JRunningJob job = jobType.DequeueJob(); job.QueueSemaphore = jobType.JobBatchQueueSemaphore; job.EndHandle = new AutoResetEvent(false); endHandlers.Add(job.EndHandle); ScheduleJobBackgroundLocal(job); startedCount++; int progress = (int)(((double)startedCount / (double)initialQueueCount) * 100.0); wk.ReportProgress(progress); } if (endHandlers.Count > 0) { WaitHandle.WaitAll(endHandlers.ToArray <AutoResetEvent>()); } PostLastJobRunEventArgs arg1 = new PostLastJobRunEventArgs(); arg1.Canceled = ew.Cancel; jobType.DoPostLJobBatch(arg1); if (ew.Cancel == false) { ew.Result = RunningJobStageEnum.complated; } } catch (Exception ex) { jobType.JobBatchLog.Error("Job Batch fatal error", ex); ew.Result = RunningJobStageEnum.exception; JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.exception); } }; mainWorker.RunWorkerCompleted += (sd, ek) => { ResetJobBatch(jobType); if (ek.Cancelled == true) { JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.aborted); } else { if (RunningJobStageEnum.exception.Equals(ek.Result)) { //do nothing } else if (RunningJobStageEnum.warning.Equals(ek.Result)) { JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.warning); } else if (RunningJobStageEnum.error.Equals(ek.Result)) { JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.error); } else { JobManager.Instance.ComplateJobBatch(jobType, RunningJobStageEnum.complated); } } }; mainWorker.ProgressChanged += (sd, pc) => { localReportProgresJobType(jobType, pc.ProgressPercentage); }; //run worker jobType.JobBatchObject = mainWorker; mainWorker.RunWorkerAsync(); }