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