定时循环任务执行

定时循环任务执行

  1 using System.Timers;
  2 
  3 /// <summary>
  4 /// 如果要实现更复杂的功能参见以下
  5 /// Cron在线表达式生成器(https://cron.ciding.cc/)
  6 /// </summary>
  7 public class ScheduledTaskExecutor
  8 {
  9     private List<TaskInfo> tasks = new List<TaskInfo>();
 10     private int currentIndex = -1; // 初始为 -1 表示还未开始执行第一个任务
 11     System.Timers.Timer timer = new System.Timers.Timer();
 12     private bool isRunning = false;
 13 
 14     public ScheduledTaskExecutor()
 15     {
 16     }
 17 
 18     private void OnTimedEvent(object? source, ElapsedEventArgs e)
 19     {
 20         var dTime = e.SignalTime;// DateTime.Now;
 21         if (isRunning)
 22         {
 23             tasks.ForEach(task =>
 24             {
 25                 task.RunTaskAsync(dTime);
 26             });
 27         }
 28     }
 29 
 30     internal void AddTask(Action<TaskInfo> action, TimeSpan timeSpan, string? descript = null)
 31     {
 32         lock (tasks)
 33         {
 34             tasks.Add(new TaskInfo(action, timeSpan, ""));
 35         }
 36     }
 37     internal void AddTask(TaskInfo taskInfo)
 38     {
 39         lock (tasks)
 40         {
 41             tasks.Add(taskInfo);
 42         }
 43     }
 44 
 45     public void Start()
 46     {
 47         timer = new System.Timers.Timer();
 48         timer.AutoReset = true;
 49         timer.Elapsed += OnTimedEvent;
 50         isRunning = true;
 51         timer.Start();
 52         //Task.Run(new Action(() =>
 53         //{
 54 
 55         //    do
 56         //    {
 57         //        //Console.WriteLine(DateTime.Now);
 58         //        var dt = DateTime.Now;// e.SignalTime;
 59         //        try
 60         //        {
 61         //            //Console.WriteLine($"{dt:hh:mm:ss.ffff}");
 62         //            tasks.ForEach(task =>
 63         //            {
 64         //                task.RunTaskAsync(dt);
 65         //            });
 66         //        }
 67         //        catch (Exception ex)
 68         //        {
 69 
 70         //        }
 71         //        Thread.Sleep(100);
 72         //    } while (true);
 73         //})); 
 74     }
 75 
 76     public void Stop()
 77     {
 78         if (isRunning)
 79         {
 80             isRunning = false;
 81             timer.Stop();
 82         }
 83     }
 84 
 85     public void ClearTasks()
 86     {
 87         lock (tasks)
 88         {
 89             tasks.Clear();
 90         }
 91     }
 92 
 93 
 94 }
 95 /// <summary>
 96 /// 任务信息
 97 /// </summary>
 98 public class TaskInfo
 99 {
100 
101     /// <summary>
102     /// 执行动作
103     /// </summary>
104     //public Action WorkTaskAction { get; }
105     public Action<TaskInfo> WorkTaskAction1 { get; private set; }
106 
107     /// <summary>
108     /// 时间间隔
109     /// </summary>
110     public TimeSpan TimeSpan { get; }
111     /// <summary>
112     /// 下一次执行时间
113     /// </summary>
114     public DateTime NextRunTime { get; private set; }
115     public string Descript { get; }
116 
117     /// <summary>
118     /// 是否异步执行
119     /// </summary>
120     public bool IsAsync { get; set; } = false;
121     /// <summary>
122     /// 终止时间
123     /// </summary>
124     public DateTime EndDate { get; set; }
125     /// <summary>
126     ///  执行次数
127     /// </summary>
128     public int RunCount { get; private set; } = 0;
129 
130 
131     public TaskInfo(Action<TaskInfo> action, TimeSpan timeSpan, string? descript = null)
132     {
133         WorkTaskAction1 = action;
134         this.TimeSpan = timeSpan;
135         NextRunTime = (DateTime.Now + timeSpan);
136         Descript = descript ?? WorkTaskAction1.Method.Name;
137     }
138 
139     public TaskInfo(TimeSpan timeSpan)
140     {
141         this.TimeSpan = timeSpan;
142     }
143 
144     /// <summary>
145     ///  
146     /// </summary>
147     /// <param name="nowDTime">当前时间</param>
148     internal void RunTaskAsync(DateTime nowDTime)
149     {
150         if (NextRunTime < nowDTime)
151         {
152             RunCount++;
153             NextRunTime = nowDTime + TimeSpan;// dt.AddMilliseconds(Interval.TotalMilliseconds);// (DateTime.Now + Interval);
154 
155             //如果时效要求高,使用此线程池
156             //ThreadPool.QueueUserWorkItem(a =>
157             //{
158             //    WorkTaskAction1?.Invoke(this);
159             //});
160             //ThreadPool.QueueUserWorkItem(a =>
161             //{
162             //    WorkTaskAction?.Invoke();
163             //}); 
164             Task.Run(() =>
165             {
166                 WorkTaskAction1?.Invoke(this);
167             }).ContinueWith(t =>
168             {
169                 if (t.IsFaulted) // 检查任务是否因为未处理的异常而错误
170                 {
171                     // 打印异常信息或执行其他错误处理
172                     foreach (var innerException in t.Exception.Flatten().InnerExceptions)
173                     {
174                         Console.WriteLine($"[{Descript}]Exception: " + innerException.Message);
175                     }
176                 }
177                 else
178                 {
179                     Console.WriteLine($"[[{Descript}]任务完成事件触发!");
180                 }
181             }, TaskContinuationOptions.ExecuteSynchronously); //.RunSynchronously()//.Wait(); 
182 
183         }
184 
185     }
186     /// <summary>
187     /// 开始时间,如果要从中午12点开始执行[yyyy.MM.dd 12:00:00]
188     /// </summary>
189     /// <param name="v">yyyy.MM.dd HH:mm:ss</param>
190     /// <returns></returns>
191     internal TaskInfo StartDate(string v)
192     {
193         NextRunTime = DateTime.Parse(DateTime.Now.ToString(v));// DateTime.ParseExact(DateTime.Now.ToString(v), "yyyy.MM.dd HH:mm:ss");
194         if (NextRunTime < DateTime.Now)
195         {
196             NextRunTime = DateTime.Parse(DateTime.Now.AddDays(1).ToString(v));
197         }
198         return this;
199     }
200 }
201 
202 // 示例代码
203 class Program
204 {
205     static void Main(string[] args)
206     {
207         var executor = new ScheduledTaskExecutor();
208 
209         executor.AddTask((info) => Console.WriteLine($"Task 1 executed at 10s,{DateTime.Now:HH:mm:sss.fff},{info.RunCount}"), TimeSpan.FromSeconds(10));
210         
211         executor.AddTask((info) =>
212         {
213             Console.WriteLine($"Task 2 executed at 1.0s ,{DateTime.Now:HH:mm:sss.fff},{info.RunCount}");
214             var ttemp = new Random().Next(0, 10);
215             if (ttemp > 5)
216             {
217                 throw new Exception($"{ttemp},throw new Exception sdfsdf");
218             }
219         }, TimeSpan.FromSeconds(1.0));
220         executor.AddTask(TestFunction, TimeSpan.FromSeconds(0.5));
221         var taskInfo = new TaskInfo(TestFunction, TimeSpan.FromSeconds(0.5),"初始开始时间执行").StartDate("yyyy.MM.dd HH:32:00"); 
222         executor.AddTask(taskInfo);
223         executor.Start();
224 
225         Console.WriteLine("Press any key to stop...");
226 
227         Console.ReadKey();
228 
229         executor.Stop();
230     }
231 
232     private static void TestFunction(TaskInfo info)
233     {
234         Console.WriteLine($"{info.Descript} executed at {info.TimeSpan} ,{DateTime.Now:HH:mm:sss.fff} {info.RunCount}");
235         var ttemp = new Random().Next(0, 10);
236         if (ttemp > 5)
237         {
238             throw new Exception($"{ttemp},XXXException,执行次数 {info.RunCount}");
239         }
240     }
241 }

 

posted @ 2024-09-14 11:45  我是猴子  阅读(22)  评论(0)    收藏  举报