public override void Run()
        {
            if (DebugContainer.Debuggers == null || UnitContainer.Units == null)
            {
                throw new Exception("JobManager have not been initialized");
            }

            //UnitContainer.InvokeALL();

            if (t != null)
            {
                t.Start();

                _baseKey = new JobMessage() { Category = "02", Name = this.Name, BaseKey = Guid.NewGuid() };

                //LogInfor.GetLogger<TimerLogger>().WriteInfo(_baseKey.Format() + " - Left time[" + (t.Interval/100).ToString() + "s]", "", "");
            }
        }
        public override void Run()
        {
            var baseKey = new JobMessage() { Category = "01", Name = this.Name, BaseKey = Guid.NewGuid() };

            //the time at which the job will run
            var currentBaseTimePoint = DateTime.Now.Date.Add(startSpan);

            var baseDate = DateTime.Now <= currentBaseTimePoint ? currentBaseTimePoint.AddDays(-1) : currentBaseTimePoint;

            while (_running)
            {
                var nextDay = baseDate.AddDays(1);
                //current data is greater than baseDate if the job is running slowly
                while (nextDay < DateTime.Now)
                {
                    baseDate = nextDay;
                    nextDay = nextDay.AddDays(1);
                }
                var baseTime = nextDay - baseDate;

                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                {
                    if (UnitContainer != null && _running)
                    {
                        //Store the info of timer
                        if (!this.Parameters.AllKeys.Contains(JobDictionary.JOB_INTERNAL_TIMER_PATTERN))
                        {
                            this.Parameters.Add(JobDictionary.JOB_INTERNAL_TIMER_PATTERN, null);
                        }
                        if (!this.Parameters.AllKeys.Contains(JobDictionary.JOB_INTERNAL_TIMER_TIME))
                        {
                            this.Parameters.Add(JobDictionary.JOB_INTERNAL_TIMER_TIME, Parameters["jobTime"]);
                        }

                        UnitContainer.InvokeALL(this.Parameters);
                    }
                    baseDate = nextDay;
                    GC.Collect();
                    GC.WaitForFullGCComplete();
                }
            }
        }
        /// <summary>
        /// Execute timing
        /// </summary>
        /// <param name="baseTime"></param>
        /// <param name="baseDate"></param>
        /// <param name="baseKey"></param>
        /// <param name="IsJobRunning"></param>
        /// <returns></returns>
        public static bool Pending(TimeSpan baseTime, DateTime baseDate, JobMessage baseKey, bool IsJobRunning = false)
        {
            //When job is running, stop timing
            if (!IsJobRunning)
            {
                TimeSpan interval = DateTime.Now.Subtract(baseDate);

                var subtract = interval.Subtract(baseTime);

                //set accuracy rating to second, as it is impossible to do something under nanosecond
                var secondTicks = Math.Floor(Convert.ToDouble(subtract.Ticks / 10000000));

                Task.Factory.StartNew(r =>
                {
                    //LogInfor.GetLogger<TimerLogger>().WriteInfo(baseKey.Format() + " - Left time[" + (secondTicks * -1).ToString() + "s]", "", "");
                }, TaskCreationOptions.PreferFairness);

                //when job is running at the first time, interval could greater than 0
                if (secondTicks >= 0)
                {
                    Task.Factory.StartNew(r =>
                    {
                        //LogInfor.GetLogger<TimerLogger>().WriteInfo(baseKey.Format() + " - Start job", "", "");
                    }, TaskCreationOptions.PreferFairness);

                    return false;
                }
                else
                {
                    var halfofsubstract = Math.Abs(subtract.Ticks / 20000);

                    //pending for half of the diffentce between interval and baseTimes to free the CPU resouces for this thread
                    Thread.Sleep(Convert.ToInt32(halfofsubstract));
                    return true;
                }
            }
            else
            {
                return true;
            }
        }
        public override void Run()
        {
            if (DebugContainer.Debuggers == null || UnitContainer.Units == null)
            {
                throw new Exception("JobManager have not been initialized");
            }

            DateTime baseDate = new DateTime();

            if (JobTimeFormatter != null)
            {
                baseDate = JobTimeFormatter.FormatTime;
            }

            JobMessage baseKey = new JobMessage() { Category = "00", Name = this.Name, BaseKey = Guid.NewGuid() };

            while (_running)
            {
                try
                {
                    //By specified time
                    if (JobTimeFormatter != null)
                    {
                        TimeSpan baseTime = new TimeSpan();
                        switch (JobTimeFormatter.Type)
                        {
                            case JobDictionary.JobTimeType.M:
                                var nextYear = baseDate.AddYears(1);
                                //current data is greater than baseDate if the job is running slowly
                                while (nextYear < DateTime.Now)
                                {
                                    baseDate = nextYear;
                                    nextYear = nextYear.AddYears(1);
                                }
                                baseTime = nextYear - baseDate;
                                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                                {
                                    _run();
                                    //Prepare for the next plan
                                    baseDate = nextYear;
                                }
                                break;
                            case JobDictionary.JobTimeType.D:
                                var nextMonth = baseDate.AddMonths(1);
                                //current data is greater than baseDate if the job is running slowly
                                while (nextMonth < DateTime.Now)
                                {
                                    baseDate = nextMonth;
                                    nextMonth = nextMonth.AddMonths(1);
                                }
                                baseTime = nextMonth - baseDate;
                                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                                {
                                    _run();
                                    baseDate = nextMonth;
                                }
                                break;
                            case JobDictionary.JobTimeType.h:
                                var nexDay = baseDate.AddDays(1);
                                //current data is greater than baseDate if the job is running slowly
                                while (nexDay < DateTime.Now)
                                {
                                    baseDate = nexDay;
                                    nexDay = nexDay.AddDays(1);
                                }
                                baseTime = nexDay - baseDate;
                                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                                {
                                    _run();
                                    baseDate = nexDay;
                                }
                                break;
                            case JobDictionary.JobTimeType.m:
                                var nextHour = baseDate.AddHours(1);
                                //current data is greater than baseDate if the job is running slowly
                                while (nextHour < DateTime.Now)
                                {
                                    baseDate = nextHour;
                                    nextHour = nextHour.AddHours(1);
                                }
                                baseTime = nextHour - baseDate;
                                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                                {
                                    _run();
                                    baseDate = nextHour;
                                }
                                break;
                            case JobDictionary.JobTimeType.s:
                                var nextMinute = baseDate.AddMinutes(1);
                                //current data is greater than baseDate if the job is running slowly
                                while (nextMinute < DateTime.Now)
                                {
                                    baseDate = nextMinute;
                                    nextMinute = nextMinute.AddMinutes(1);
                                }
                                baseTime = nextMinute - baseDate;
                                if (!TimePending.Pending(baseTime, baseDate, baseKey))
                                {
                                    _run();
                                    baseDate = nextMinute;
                                }
                                break;
                        }
                    }
                }
                catch
                {
                }
            }
        }