static void ExecuteJob(Object jobExecutionContextObject)
        {
            JobExecutionContext jobExecutionContext = (JobExecutionContext)jobExecutionContextObject;
            JobContext          jobContext          = jobExecutionContext.JobContext;

            Debug.WriteLine(DateTime.Now + " : " + jobContext.JobData.Id + " start thread. Queue = " + jobExecutionContext.ExecutionQueue.Id);

            try
            {
                IJobExecutorFactory jobExecutorFactory = new JobExecutorFactory();
                IJobExecutor        jobExecutor        = jobExecutorFactory.GetJobExecutor(jobContext);
                jobExecutor.ExecuteJob(jobContext);
                TimedThreadExecutionQueue queue = (TimedThreadExecutionQueue)jobExecutionContext.ExecutionQueue;
                lock (queue.workers)
                {
                    queue.workers.Remove(jobExecutionContext);
                }
                var jobFinishedEvent = queue.JobFinishedExecuting;
                if (jobFinishedEvent != null)
                {
                    jobFinishedEvent(queue, new JobFinishedExecutingEventArgs(jobContext.JobData.Id));
                }
            }
            catch (ThreadAbortException)
            {
                string message = string.Format("Job has exceeded the ShutdownTimeout and was terminated abnormally.", jobContext.JobData.Id);
                jobContext.JobManager.JobStore.SetJobStatus(jobContext.JobData.Id, JobStatus.Executing, JobStatus.ShutdownTimeout, message);
            }

            Debug.WriteLine(DateTime.Now + " : " + jobContext.JobData.Id + " end thread. Queue = " + jobExecutionContext.ExecutionQueue.Id);
        }
        static void ExecuteJob(Object jobExecutionContextObject)
        {
            JobExecutionContext jobExecutionContext = (JobExecutionContext)jobExecutionContextObject;
            JobContext          jobContext          = jobExecutionContext.JobContext;

            Debug.WriteLine(DateTime.Now.ToString("dd/mm/yyyy HH:mm:ss:fffffff") + " : " + jobContext.JobData.Id + " ExecuteJob Enter. Queue = " + jobExecutionContext.ExecutionQueue.Id);
            try
            {
                IJobExecutorFactory jobExecutorFactory = new JobExecutorFactory();
                IJobExecutor        jobExecutor        = jobExecutorFactory.GetJobExecutor(jobContext);
                jobExecutor.ExecuteJob(jobContext);
                ThreadPoolExecutionQueue queue = (ThreadPoolExecutionQueue)jobExecutionContext.ExecutionQueue;
                lock (queue.activeThreads)
                {
                    queue.activeThreads = (uint)queue.activeThreads - 1;
                    var jobFinishedEvent = queue.JobFinishedExecuting;
                    if (jobFinishedEvent != null)
                    {
                        jobFinishedEvent(queue, new JobFinishedExecutingEventArgs(jobContext.JobData.Id));
                    }
                }
            }
            catch (ThreadAbortException)
            {
                string message = string.Format("Job has exceeded the ShutdownTimeout and was terminated abnormally.", jobContext.JobData.Id);
                jobContext.JobManager.JobStore.SetJobStatuses(new long[] { jobContext.JobData.Id }, JobStatus.Executing, JobStatus.ShutdownTimeout, message);
            }
            Debug.WriteLine(DateTime.Now.ToString("dd/mm/yyyy HH:mm:ss:fffffff") + " : " + jobContext.JobData.Id + " ExecuteJob Exit. Queue = " + jobExecutionContext.ExecutionQueue.Id);
        }