using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Wicture.DbRESTFul; using Wicture.DbRESTFul.Configuration; namespace JiaZhiQuan { public abstract class AbstractControlledScheduleService : IHostedService, IDisposable { public int Interval { get; set; } public Timer TickTimer { get; private set; } public string Name { get; private set; } public bool RunImmediately { get; private set; } public readonly static Dictionary RunStates = new Dictionary(); /// /// 是否忽略appsettings.json中的启用配置(DisabledSchedules/EnabledSchedules) /// public bool IgnoreStateConfig { get; set; } = false; /// /// ScheduleService基类,默认服务会立即启动 /// /// 间隔时间:1000 = 1秒 public AbstractControlledScheduleService(int timerInterval, bool runImmediately = true) { Name = GetType().Name; Interval = timerInterval; RunImmediately = runImmediately; if (RunStates.ContainsKey(Name)) { RunStates[Name] = "Created"; } else { RunStates.Add(Name, "Created"); } } /// /// 返回 false 时,此次不执行 /// public virtual bool BeforeRun() { return true; } public abstract Task Run(); private async void TimerRun(object state) { if (BeforeRun()) { try { var stime = DateTime.Now; RunStates[Name] = "Running"; await Run(); RunStates[Name] = "Completed"; var t = (DateTime.Now - stime).TotalSeconds; // 如果大于1秒的任务,则Log记录 if (t > 1) { LoggerManager.Logger.Info($"{Name}执行时间:${t.ToString("0.###")}s"); } } catch (Exception ex) { LoggerManager.Logger.Error(ex, Name + "执行出错\r\n" + ex.Message); RunStates[Name] = "Error"; } } TickTimer.Change(Interval, Timeout.Infinite); } public async Task StartAsync(CancellationToken cancellationToken) { if (!IgnoreStateConfig) { // 判断是否要执行 string disabledSchedules; var rst = ConfigurationManager.Settings.Variables.TryGetValue("DisabledSchedules", out disabledSchedules); if (rst) { if (disabledSchedules.Split(',').Contains(Name)) { LoggerManager.Logger.Error($"ScheduleService【{GetType().Name}】被禁用"); await Task.CompletedTask; RunStates[Name] = "Stopped"; return; } } string enabledSchedules; rst = ConfigurationManager.Settings.Variables.TryGetValue("EnabledSchedules", out enabledSchedules); if (rst && !string.IsNullOrEmpty(enabledSchedules)) { if (!enabledSchedules.Split(',').Contains(Name)) { LoggerManager.Logger.Error($"ScheduleService【{GetType().Name}】被禁用"); await Task.CompletedTask; RunStates[Name] = "Stopped"; return; } } } LoggerManager.Logger.Info($"ScheduleService【{GetType().Name}】已启动"); TickTimer = new Timer(TimerRun, null, RunImmediately ? 0 : Interval, Timeout.Infinite); RunStates[Name] = "Started"; await Task.CompletedTask; } public async Task StopAsync(CancellationToken stoppingToken) { LoggerManager.Logger.Info($"ScheduleService【{GetType().Name}】已停止"); TickTimer?.Change(Timeout.Infinite, 0); await Task.CompletedTask; } public void Dispose() { RunStates[Name] = "Stopped"; TickTimer?.Dispose(); TickTimer = null; GC.SuppressFinalize(this); } } }