internal void BuildServices(IServiceCollection services) { var options = new CrontabOptions() { Assemblies = assemblies, ScanAllAssembly = ScanAllAssembly }; services.AddSingleton(options); services.AddSingleton <CrontabService>(); }
private List <TypeInfo> GetTypeInfos(CrontabOptions options) { HashSet <Assembly> assemblys = new HashSet <Assembly>(); if (options.ScanAllAssembly) { var entryAssembly = Assembly.GetEntryAssembly(); var dependencyContext = DependencyContext.Load(entryAssembly); if (dependencyContext == null) { assemblys.Add(entryAssembly); } else { var assName = Assembly.GetExecutingAssembly().GetName().Name; var libs = dependencyContext.RuntimeLibraries.Where(lib => lib.Dependencies.Any(dep => string.Equals(assName, dep.Name, StringComparison.Ordinal))); var assNames = libs.SelectMany(lib => lib.GetDefaultAssemblyNames(dependencyContext)); foreach (var name in assNames) { var assembly = Assembly.Load(new AssemblyName(name.Name)); assemblys.Add(assembly); } } } if (options.Assemblies != null && options.Assemblies.Count > 0) { foreach (var assembly in options.Assemblies) { assemblys.Add(assembly); } } if (assemblys.Count == 0) { assemblys.Add(Assembly.GetEntryAssembly()); } var types = assemblys.SelectMany(a => a.DefinedTypes.Where(y => y.GetCustomAttribute <CrontabJobAttribute>() != null)).ToList(); return(types); }
/// <summary> /// /// </summary> /// <param name="services"></param> public CrontabService(IServiceProvider services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } var options = services.GetService <CrontabOptions>(); if (options == null) { options = new CrontabOptions(); } this.logger = services.GetService <ILogger>(); var types = GetTypeInfos(options); var list = new List <CrontabExecutor>(); foreach (var type in types) { foreach (var method in type.DeclaredMethods) { var attribute = method.GetCustomAttribute <CrontabScheduleAttribute>(); if (attribute != null) { if (string.IsNullOrEmpty(attribute.Name)) { throw new CustomAttributeFormatException("Crontab name is empty"); } var arr = attribute.Schedule.Split('|'); if (arr.Length == 0) { throw new CustomAttributeFormatException($"Crontab '{attribute.Name}' does not have any schedule"); } var schedules = new CrontabSchedule[arr.Length]; for (int i = 0; i < arr.Length; i++) { if (CrontabSchedule.TryParse(arr[i], out CrontabSchedule schedule)) { schedules[i] = schedule; } else { throw new CustomAttributeFormatException($"Crontab '{attribute.Name}' schedule '{arr[i]}' format error"); } } var name = attribute.Name; if (string.IsNullOrEmpty(name)) { name = method.Name; } var item = new CrontabExecutor(name, services, cts.Token, type, method, schedules, attribute.AllowConcurrentExecution, attribute.RunImmediately); if (!executorDict.ContainsKey(item.Name)) { executorDict.Add(item.Name, item); if (attribute.AutoEnable) { item.Enable(); } } else { throw new CustomAttributeFormatException($"Crontab '{item.Name}' name is duplicate"); } } } } var dt = DateTime.Now; dt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0); var next = dt.AddMinutes(1); var due = Convert.ToInt32(Math.Ceiling((next - DateTime.Now).TotalMilliseconds)); Task.Factory.StartNew(async() => { try { await Task.Delay(due, cts.Token); Execute(); } catch (Exception ex) { if (logger != null) { logger.LogError(ex, "Execute error"); } } }, cts.Token); }