Windows服务定时执行任务

1.创建多线程类

   /// <summary>
    /// 多线程
    /// </summary>
    public abstract class MuliThread<T>
    {
        /// <summary>
        /// 线程
        /// </summary>
        private static readonly List<Thread> Threads = new List<Thread>();
        /// <summary>
        /// 日志
        /// </summary>
        private static readonly Log Log = new Log("Tasks");
        private static readonly List<Func<bool>> ExitFuncs = new List<Func<bool>>();

        #region 启动&停止

        /// <summary>
        /// 启动任务
        /// </summary>
        /// <param name="type">0:异步启动1:同步启动</param>
        public static void Start(int type = 0)
        {
            typeof(T).GetConstructors().First().Invoke(null);
            new Thread(Begin).Start(type);
        }
        /// <summary>
        /// 启动
        /// </summary>
        private static void Begin(object type)
        {
            var typeName = typeof(T).Name;
            var threads = Threads.Where(a => a.Name.StartsWith(typeName)).ToArray();
            foreach (var thread in threads)
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                var times = 0;
                while (thread.ThreadState == (ThreadState.Background | ThreadState.Unstarted) && times < 10)
                {
                    try
                    {
                        thread.Start();
                    }
                    catch (Exception e)
                    {
                        times++;
                        Log.Error(e.Message + e.StackTrace);
                    }
                    Thread.Sleep(100);
                }
            }

            Log.Info(typeName, "启动成功,共启动个{0}线程".Formats(threads.Length));
            if (type.ConvertTo(0) != 1) return;
            Thread.Sleep(1000);
            foreach (var thread in threads)
            {
                try
                {
                    thread.Join();
                }
                catch (Exception e)
                {
                    Log.Error(e.Message + e.StackTrace);
                }
            }
        }

        private static void End()
        {
            var typeName = typeof(T).Name;
            try
            {
                Log.Info(typeName, "共 {0} 个线程".Formats(Threads.Count));

                var threads = Threads.Where(a => a.Name.StartsWith(typeName)).ToArray();
                while (threads.Count(a => a != null && a.IsAlive) > 0)
                {
                    foreach (var thread in threads)
                    {
                        if (thread.IsAlive)
                        {
                            thread.Abort();
                            Log.Info(typeName, "正在终止线程 {0}".Formats(thread.ManagedThreadId));
                        }
                    }

                    Log.Info(typeName, "剩余 {0} 个未终止".Formats(threads.Count(a => a != null && a.IsAlive)));

                    Thread.Sleep(200);
                }

                Log.Info(typeName, "线程全部正常停止");
            }
            catch (Exception e)
            {
                Log.Error(typeName, "{0} {1}".Formats(e.Message, e.StackTrace));
            }
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        public static void Exit()
        {
            foreach (var func in ExitFuncs)
            {
                func();
            }
            new Thread(End).Start();
        }

        #endregion

        protected static void LogDebug(string log)
        {
            Log.Debug(typeof(T).Name, log);
        }
        protected static void LogInfo(string log)
        {
            Log.Info(typeof(T).Name, log);
        }
        protected static void LogTicketInfo(string log)
        {
            Log.TicketInfo(typeof(T).Name, log);
        }
        protected static void LogTicketError(string log)
        {
            Log.TicketError(typeof(T).Name, log);
        }
        protected static void LogWarn(string log)
        {
            Log.Warn(typeof(T).Name, log);
        }
    
        protected static void LogError(string log)
        {
            Log.Error(typeof(T).Name, log);
        }
     
        /// <summary>
        /// 添加任务
        /// </summary>
        protected static void AddTask(ThreadStart threadStart)
        {
            lock (Threads)
            {
                Threads.Add(new Thread(threadStart) { Name = typeof(T).Name });
            }
        }
        /// <summary>
        /// 批量添加任务
        /// </summary>
        protected static void AddTasks(IEnumerable<ThreadStart> threadStarts)
        {
            foreach (var threadStart in threadStarts)
            {
                AddTask(threadStart);
            }
        }

        /// <summary>
        /// 添加退出时执行任务
        /// </summary>
        protected static void AddExitCall(Func<bool> func)
        {
            ExitFuncs.Add(func);
        }
    }

2. 创建服务调用类

  public class AutoAddIssues : MuliThread<AutoAddIssues>
    {
        public AutoAddIssues()
        {
            StartAddIssue();
        }
        private static void StartAddIssue()
        {
            AddTask(AddIssueRun);
            AddTask(ExcCurentStatus);
            AddTask(OpenStart);
        }
        private static void ExcCurentStatus()
        {
            try
            {
                System.Timers.Timer timer = new System.Timers.Timer();
                timer.Interval = 60000;
                timer.Elapsed += timer_Elapsed;
                timer.AutoReset = true;
                timer.Start();
            }
            catch (Exception ex)
            {
                new Log("ExcCurentStatus").Error(string.Format("Szpl.SSQAutoService.Task Start Error:{0}", ex.ToString()));
                return;
            }
            new Log("ExcCurentStatus").Info(string.Format("Szpl.SSQAutoService.Task Start ....."));
        }

        static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                DateTime dt1 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 21, 10, 01);
                DateTime dt2 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 21, 14, 50);
                TimeSpan ts1 = dt1.Subtract(DateTime.Now);
                TimeSpan ts2 = dt2.Subtract(DateTime.Now);
                if (ts1.TotalSeconds < 0 && ts2.TotalSeconds > 1)
                {
                    (sender as System.Timers.Timer).Interval = 23 * 60 * 60 * 1000;
                    UpdateIssueStatus.Execute();
                    new Log("ExcCurentStatus").Info(string.Format("Szpl.SSQAutoService.Task Start Time : {0},Does not exist", DateTime.Now));
                }
                else
                {
                    (sender as System.Timers.Timer).Interval = 60000;
                }
            }
            catch (Exception ex)
            {
                new Log("ExcCurentStatus").Info(string.Format("Error:{0}", ex.ToString()));
            }
        }


        public static void OpenStart()
        {
            try
            {
                System.Timers.Timer timer = new System.Timers.Timer();
                timer.Interval = 60000;
                timer.Elapsed += timer_Elapsed_OpenStart;
                timer.AutoReset = true;
                timer.Start();
            }
            catch (Exception ex)
            {
                new Log("ExcCurentStatus").Error(string.Format("Szpl.SSQAutoService.Task Start Error:{0}", ex.ToString()));
                return;
            }
            new Log("ExcCurentStatus").Info(string.Format("Szpl.SSQAutoService.Task Start ....."));
        }
        static void timer_Elapsed_OpenStart(object sender, System.Timers.ElapsedEventArgs e)
        {
            DateTime dt1 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 21, 15, 01);
            DateTime dt2 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 00, 01);
            TimeSpan ts1 = dt1.Subtract(DateTime.Now);
            TimeSpan ts2 = dt2.Subtract(DateTime.Now);
            if (ts1.TotalSeconds < 0 && ts2.TotalSeconds > 1)
            {
                List<T_Issues> Issues = T_Issues.Select(" Id,RIGHT(Name,5) Name,LotteryId ", " CurrentStatus=3 and IsOpened=0 and OpenLotteryNnumber='' ");
                if (Issues == null || Issues.Count <= 0)
                {
                    (sender as System.Timers.Timer).Interval = 60000;
                    return;
                }
                else
                {
                    UpdateIssueStatus.GetAgent("3", "ssq", Issues[0].Name.Trim(), Issues[0].Id);
                }

                Issues = T_Issues.Select(" Id,Name,LotteryId,OpenLotteryNnumber ", " CurrentStatus=3 and OpenLotteryNnumber<>'' and IsOpened=0 ");
                if (Issues.Count <= 0)
                {
                    (sender as System.Timers.Timer).Interval = 10000;
                    new Log("OpenStart").Warn("OpenStart -->> select issues < 0 ");
                    return;
                }

                (sender as System.Timers.Timer).Interval = 23 * 60 * 60 * 1000;

                AutoOpened.Execute(Issues);

            }
            else
            {
                (sender as System.Timers.Timer).Interval = 60000;
            }
        }

        private static void AddIssueRun()
        {
            int sleepTime = 1000;
            while (true)
            {
                try
                {
                    SelectIssue(ref sleepTime);
                }
                catch (Exception ex)
                {
                    LogError("添加期号失败 {0} {1}".Formats(ex.Message, ex.StackTrace));
                }

                System.Threading.Thread.Sleep(sleepTime);
            }
        }
        private static void SelectIssue(ref int sleepTime)
        {
            try
            {
                string strSql = @"SELECT LotteryID,Name,StartTime,EndTime FROM T_Issues WHERE ID IN(
                                    SELECT ID FROM (
                                    SELECT MAX(ID) AS ID,LotteryID,(SELECT COUNT(1) FROM T_Issues WHERE EndTime>GETDATE() AND LotteryID = a.LotteryID) AS Num FROM T_Issues a
                                    WHERE a.LotteryID=5 GROUP BY a.LotteryID) t WHERE Num<50)";

                List<T_Issues> list = Sql.Select<T_Issues>(strSql);
                if (list == null)
                {
                    LogError("读取SSQ数据查询失败");
                    return;
                }

                if (list.Count == 0)
                {
                    sleepTime = 600000;
                }

                foreach (T_Issues Issues in list)
                {
                    AddIssues(Issues);
                }

            }
            catch (Exception ex)
            {
                LogError("SSQ Mathod SelectIssus Error {0}".Formats(ex.Message));
            }
        }
        private static void AddIssues(T_Issues Issues)
        {
            var lotId = Issues.LotteryId;
            var lastIssueName = Issues.Name;
            var lastIssueStart = Issues.StartTime;
            var lastIssueEndTime = Issues.EndTime;

            var issuePre = long.Parse(lastIssueName.Substring(0, lastIssueName.Length - 3));
            var issueName = long.Parse(lastIssueName.Substring(lastIssueName.Length - 3));
            var newStart = new DateTime(lastIssueEndTime.Year, lastIssueEndTime.Month, lastIssueEndTime.Day, lastIssueStart.Hour, lastIssueStart.Minute, lastIssueStart.Second);

            var newEnd = lastIssueEndTime;
            do
            {
                newEnd = newEnd.AddDays(1);
            }
            while (!IsCanAdd(lotId, newEnd));

            if (lastIssueEndTime.Year != newEnd.Year)
            {
                issuePre = newEnd.Year;
                issueName = 1;
            }
            else
            {
                issueName++;
            }

            Issues.LotteryId = lotId;
            Issues.Name = issuePre + issueName.ToString().PadLeft(3, '0');
            Issues.StartTime = newStart;
            Issues.EndTime = newEnd;

            var newId = Issues.InsertId("LotteryID={0} AND Name={1}".Formats(Issues.LotteryId, Issues.Name));
            if (newId < 1)
            {
                LogError("添加期号错误{0} {1} {2} {3}".Formats(Issues.LotteryId, Issues.Name, Issues.StartTime, Issues.EndTime));
            }
        }
        private static bool IsCanAdd(long lotid, DateTime day)
        {
            switch (lotid)
            {
                case 3:
                    if (day.DayOfWeek == DayOfWeek.Tuesday || day.DayOfWeek == DayOfWeek.Friday || day.DayOfWeek == DayOfWeek.Sunday)
                        return true;
                    break;
                case 5:
                    if (day.DayOfWeek == DayOfWeek.Tuesday || day.DayOfWeek == DayOfWeek.Thursday || day.DayOfWeek == DayOfWeek.Sunday)
                        return true;
                    break;
                case 13:
                    if (day.DayOfWeek == DayOfWeek.Monday || day.DayOfWeek == DayOfWeek.Wednesday || day.DayOfWeek == DayOfWeek.Friday)
                        return true;
                    break;
                case 39:
                    if (day.DayOfWeek == DayOfWeek.Monday || day.DayOfWeek == DayOfWeek.Wednesday || day.DayOfWeek == DayOfWeek.Saturday)
                        return true;
                    break;
                default:
                    break;
            }
            return false;
        }
    }

3.必要属性配置

4. 项目框架结构

原文地址:https://www.cnblogs.com/sunxuchu/p/5424363.html