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. 项目框架结构