zoukankan      html  css  js  c++  java
  • c# 定时启动一个操作、任务(版本2)

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Threading;
    using System.Timers;
    using System.Windows;
    
    /*
    功能:定时启动一个操作。
    作者:李茂平
    用法:
    this.TimeWork = new ClassLibraryEF.TimeWork(this.MainWindow);
    
    this.TimeWork.AddWork(new ClassLibraryEF.TimeWorkItem()
    {
        任务名称 = "任务名称1",
        Work = this.DoWork1,
        计划启动日期 = "周六 5月1日 9月1日 11月1日",
        计划启动时间 = "08:00",
      
        任务说明 = "任务说明"
    });
    this.TimeWork.AddWork(new ClassLibraryEF.TimeWorkItem()
    {
        任务名称 = "任务名称2",
        Work = this.DoWork2,
        计划启动时间 = "09:30 10:30 11:31 14:00 15:01",
        任务说明 = "任务说明"
    });
    this.TimeWork.SetEnable(true);
    
    */
    
    namespace ClassLibraryEF
    {
        /// <summary>
        /// 定时执行任务的类,精度每分钟
        /// </summary>
        public class TimeWork : ObservableCollection<TimeWorkItem>
        {
            /// <summary>
            /// 使用多线程计时器
            /// </summary>
            private readonly System.Timers.Timer timer1 = new System.Timers.Timer();
    
            /// <summary>
            /// 运行的分钟数
            /// </summary>
            private int CountMin { get; set; } = 0;
    
            /// <summary>
            /// 当任务完成时
            /// </summary>
            public Action<TimeWorkItem, TimeWorkLogItem> OnWorkFinished { get; set; }
    
            /// <summary>
            /// 执行记录
            /// </summary>
            public ObservableCollection<TimeWorkLogItem> LogItems { get; set; } = new ObservableCollection<TimeWorkLogItem>();
    
            public Window MainWindow { get; }
    
            /// <summary>
            /// 构造函数,创建精度为1分钟的定时器
            /// </summary>
            public TimeWork(Window mainwindow)
            {
                this.MainWindow = mainwindow;
    
                this.timer1.Interval = 1 * 1000 * 60;    // 1分钟的定时器
                this.timer1.Elapsed += timerMinute_Elapsed;
                this.timer1.Enabled = false;    // 初始化为不发生定时事件
            }
    
            /// <summary>
            /// 是否启用定时任务
            /// </summary>
            /// <param name="bEnable"></param>
            public void SetEnable(bool bEnable)
            {
                this.timer1.Enabled = bEnable;
                if (bEnable)
                    ResetRunTime();
            }
    
            /// <summary>
            /// 定时器时间到,检查启动项目
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void timerMinute_Elapsed(object sender, ElapsedEventArgs e)
            {
                CountMin++;
    
                if (CountMin % 60 == 0) // 每1个小时重置一次
                {
                    ResetRunTime();
                }
    
                DoTimerWork();
            }
    
            /// <summary>
            /// 重新设定运行时间
            /// </summary>
            public void ResetRunTime()
            {
                foreach (var item in this)
                {
                    item.InitRunTimes();
                }
            }
    
            /// <summary>
            /// 定时器时间到,检查启动项目
            /// </summary>
            private void DoTimerWork()
            {
                DateTime now = DateTime.Now;
                foreach (var item in this)
                {
                    foreach (var time in item.RunTimes)
                    {
                        if (time.Hours == now.Hour &&
                             time.Minutes == now.Minute)
                        {
                            Thread t = new Thread(() =>
                            {
                                this.DoWork(item);
                            });
                            t.Start();
                        }
                    }
                }
            }
    
            /// <summary>
            /// 添加一个定时执行的项目
            /// </summary>
            /// <param name="item"></param>
            public void AddWork(TimeWorkItem item)
            {
                this.Add(item);
            }
    
            /// <summary>
            /// 执行任务
            /// </summary>
            /// <param name="item"></param>
            public void DoWork(TimeWorkItem item)
            {
                if (item != null && item.Work != null)
                {
                    DateTime begin = DateTime.Now;
                    item.Work(); // 执行工作
    
                    item.上次执行时间 = begin.ToString("T");
    
                    if (item.添加到执行记录)
                        LogItem(item, begin, DateTime.Now);
                }
            }
    
            /// <summary>
            /// 添加一条记录到文件,记录已经执行的任务
            /// </summary>
            /// <param name="item"></param>
            private void LogItem(TimeWorkItem item, DateTime begin, DateTime end)
            {
                TimeWorkLogItem logItem = new TimeWorkLogItem();
    
                logItem.任务名称 = item.任务名称;
                logItem.执行时间 = begin;
                logItem.完成时间 = end;
    
                this.MainWindow.Dispatcher.Invoke(() =>
                {
                    this.LogItems.Add(logItem);
    
                    if (OnWorkFinished != null)
                    {
                        OnWorkFinished(item, logItem);
                    }
                });
            }
        }
    
        /// <summary>
        /// MVVM模式下,更改属性的通知
        /// 首先定义NotificationObject类。目的是绑定数据属性。
        /// 这个类的作用是实现了INotifyPropertyChanged接口。
        /// WPF中类要实现这个接口,其属性成员才具备通知UI的能力
        /// </summary>
    
        public class NotificationObjectEF : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void RaisePropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    
        /// <summary>
        /// 定时工作项目
        /// </summary>
        public class TimeWorkItem : NotificationObjectEF
        {
            public Action Work { get; set; }
            public string 任务名称 { get; set; }
            public string 任务说明 { get; set; }
    
            /// <summary>
            /// 设定的计划启动日期,空格分开,如:每周6,每月1,空白意味着每天
            /// 空白 -- 启动
            /// 周一 到 周日 启动
            /// 5月2日 启动
            /// </summary>
            public string 计划启动日期 { get; set; } = "每天";
    
            /// <summary>
            /// 空格分开的多个时间:15:00 16:32
            /// </summary>
            public string 计划启动时间 { get; set; }
    
            /// <summary>
            /// 间隔多少分钟重复,每天执行
            /// </summary>
            public int 间隔分钟 { get; set; }
    
            /// <summary>
            /// 是否记录到执行记录
            /// </summary>
            public bool 添加到执行记录 { get; set; } = true;
    
            private string 上次执行时间_;
    
            public string 上次执行时间
            {
                get
                {
                    return 上次执行时间_;
                }
                set
                {
                    上次执行时间_ = value;
                    RaisePropertyChanged("上次执行时间");
                }
            }
    
            /// <summary>
            /// 运行任务的时间表
            /// </summary>
            public ObservableCollection<TimeSpan> RunTimes { get; set; } = new ObservableCollection<TimeSpan>();
    
            /// <summary>
            /// 运行任务的时间表
            /// </summary>
            private string runTimeStr;
    
            /// <summary>
            /// 运行任务的时间表
            /// </summary>
            public string RunTimesStr
            {
                get
                {
                    return runTimeStr;
                }
                set
                {
                    runTimeStr = value;
                    RaisePropertyChanged("RunTimesStr");
                }
            }
    
            /// <summary>
            /// 初始化时间
            /// </summary>
            public void InitRunTimes()
            {
                // 分析时间
                RunTimes.Clear();
    
                if (!string.IsNullOrEmpty(计划启动时间) && IsTodayRun())
                {
                    string[] times = 计划启动时间.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    foreach (var item in times)
                    {
                        DateTime dt = new DateTime();
                        if (DateTime.TryParse(item, out dt))
                        {
                            RunTimes.Add(dt.TimeOfDay);
                        }
                    }
                }
    
                if (间隔分钟 > 0 && IsTodayRun() && string.IsNullOrEmpty(计划启动时间))
                {
                    DateTime now = DateTime.Now;
                    DateTime oneTime = now.AddMinutes(间隔分钟);
                    DateTime EndTime = now.AddHours(12);
    
                    while (oneTime <= EndTime)
                    {
                        RunTimes.Add(oneTime.TimeOfDay);
                        oneTime = oneTime.AddMinutes(间隔分钟);
                    }
                }
    
                // 设置字符串
                string newRunTimesStr = "";
                foreach (TimeSpan ts in RunTimes)
                {
                    newRunTimesStr += $"{ts.Hours:00}:{ts.Minutes:00} ";
                }
                RunTimesStr = newRunTimesStr;
            }
    
            /// <summary>
            /// 判断今日是否是执行日期.
            /// 空白 -- 是
            /// 周一到周日 是
            /// 5月2日 是
            /// </summary>
            /// <returns></returns>
            private bool IsTodayRun()
            {
                if (string.IsNullOrEmpty(this.计划启动日期))
                    return true;
    
                if (this.计划启动日期.Contains("每天"))
                    return true;
    
                string[] days = 计划启动日期.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in days)
                {
                    if (item.Contains("") || item.Contains("星期"))
                    {
                        if (DateTime.Now.DayOfWeek == ConvertToDayOfWeek(item))
                            return true;
                    }
                    if (item.Contains("") && item.Contains(""))
                    {
                        string full = $"{DateTime.Now.Year}年" + item;
                        if (DateTime.TryParse(full, out DateTime setDate))
                        {
                            if (setDate.Date == DateTime.Now.Date)
                                return true;
                        }
                    }
                }
                return false;
            }
    
            private DayOfWeek ConvertToDayOfWeek(string item)
            {
                switch (item)
                {
                    case "周一":
                    case "星期一":
                        return DayOfWeek.Monday;
    
                    case "周二":
                    case "星期二":
                        return DayOfWeek.Tuesday;
    
                    case "周三":
                    case "星期三":
                        return DayOfWeek.Wednesday;
    
                    case "周四":
                    case "星期四":
                        return DayOfWeek.Thursday;
    
                    case "周五":
                    case "星期五":
                        return DayOfWeek.Monday;
    
                    case "周六":
                    case "星期六":
                        return DayOfWeek.Saturday;
    
                    case "周日":
                    case "星期日":
                        return DayOfWeek.Sunday;
    
                    default:
                        return DayOfWeek.Sunday;
                }
            }
        }
    
        [Serializable]
        public class TimeWorkLogItem
        {
            /// <summary>
            /// 名称
            /// </summary>
            public string 任务名称 { get; set; }
    
            /// <summary>
            /// 上次执行时间
            /// </summary>
            public DateTime 执行时间 { get; set; }
    
            /// <summary>
            /// 完成时间
            /// </summary>
            public DateTime 完成时间 { get; set; }
        }
    }
  • 相关阅读:
    SQL Server中出现用户或角色在当前数据库已经存在的问题的解决
    vs项目中添加lib库的方法总结
    【转载】C++ Socket通信总结(附C++实现)
    【转载】windows socket函数详解
    如何在 Debian 9 下安装 LEMP 和 WHMCS 7.5
    13个云计算基础设施自动化的最佳工具
    5分钟打造一个前端性能监控工具
    我的处女作——设计模式之状态模式
    IOS逆向分析笔记——replay逆向分析
    IOS逆向分析——GL脚本的提取
  • 原文地址:https://www.cnblogs.com/lmp138/p/14672869.html
Copyright © 2011-2022 走看看