/// <summary> /// 监视轮询工作 /// 发现有可执行的任务时,启动该任务所在的驱动以使其执行。 /// Note:Working时就要每次重读配置,释放后的任务再也回不来了。 /// </summary> public void Working(object sender, ElapsedEventArgs args) { //Note:线程锁定 lock (this) { _watcher.Stop(); _log.Debug($"↓---- 任务监视轮询开始 ---- [下次轮询延时: {_watcher.Interval/1000}秒 ; 当前时间:{DateTime.Now.ToString("HH:mm:ss ffffff")}]"); TryRemoveTask(); StartSettingTasks(); _watcher.Interval = ((TimeSpan)TaskSetting.WatchTimer.WorkingInterval).TotalMilliseconds; _workTimes++; _log.DebugFormat($"↑---- 任务监视轮询结束[Times:{_workTimes}] ---- [当前时间:{DateTime.Now.ToString("HH:mm:ss ffffff")}]"); _watcher.Start(); } }
protected override OperationAggregatableMessage <FactOperation> Process(TrackedUseCase message) { _tracer.DebugFormat("Processing TUC {0}", message.Id); var receivedOperationCount = message.Operations.Sum(x => x.AffectedEntities.Changes.Sum(y => y.Value.Sum(z => z.Value.Count))); _telemetryPublisher.Publish <ErmReceivedOperationCountIdentity>(receivedOperationCount); var changes = _useCaseFiltrator.Filter(message); // TODO: вместо кучи factoperation можно передавать одну с dictionary, где уже всё сгруппировано по entity type var factOperations = changes.SelectMany(x => x.Value.Select(y => new FactOperation(_registry.GetEntityType(x.Key), y))).ToList(); _telemetryPublisher.Publish <ErmEnqueuedOperationCountIdentity>(factOperations.Count); return(new OperationAggregatableMessage <FactOperation> { TargetFlow = MessageFlow, Operations = factOperations, OperationTime = message.Context.Finished.UtcDateTime, }); }
/// <summary> /// Note:序列化,从配置中获取所有数据 /// </summary> /// <returns></returns> public void Initialize() { using (var reader = XmlReader.Create(GetFullPath(FILE_NAME))) { logRun.Debug("任务配置实例初始化开始..."); var slz = new XmlSerializer(typeof(TaskConfig)); var rst = slz.Deserialize(reader) as TaskConfig; reader.Close(); _instance = rst; //获得实例 if (_instance != null && _instance.Tasks.Count > 0) { foreach (var task in _instance.Tasks) { //相关配置初始化,保持默认值的合法性 //锁定超时至少5秒 if (task.WorkSetting.Timeout < 5) { task.WorkSetting.Timeout = 5; } var taskId = task.Meta.Id; //1. 任务Id唯一性检测 var tmpJobs = _instance.Tasks.FindAll(x => x.Meta.Id == taskId); //logRun.Debug($"jobs[{taskId}]={tmpJobs.Count}"); if (tmpJobs.Count < 2) { //没有重复的任务Id task.Meta.TaskHash = task.Type.GetHashCode(); logRun.Debug($"{task}的任务Hash:{task.Meta.TaskHash}"); } else { var msg = $"Task.Id={taskId}重复,{FILE_NAME}里每一个Job的Id必须是与其它任务的Id不同的数字。"; logRun.ErrorFormat(msg); throw new ConfigurationErrorsException(msg); } } } } if (_instance == null) { var msg = $"请查检{FILE_NAME}配置文件是否存在并且配置正确。"; logRun.ErrorFormat(msg); throw new ConfigurationErrorsException(msg); } //计时器初始化 if (_instance.WatchTimer == null) { _instance.WatchTimer = new TimerConfig(); } //初始化运行状态 //instance.Execution = ExecutionStatus.Instance(); logRun.DebugFormat("初始化一个新的XML运行状态实例"); _execution = ExecutionStatus.Instance(); //var instance = Serializer.XmlDeserializerFormFile<TaskConfig>(); //将上次运行状态恢复至本实例中 foreach (var task in _instance.Tasks) { var jobId = task.Meta.Id; //任务状态初始化或匹配 var job = _execution.Tasks[jobId]; //查询Job的运行情况 if (job == null) { logRun.DebugFormat("开始初始化任务({0})运行状态[新的]。", task.Meta.Name); task.Execution = new ExecutionInfo(); //初始化新执行状态 _execution.Tasks.Add(task.Meta); //工作运行状态增加 } else { logRun.DebugFormat("开始读取任务({0})运行状态[已有的]。", task.Meta.Name); //task.Execution = _execution.Tasks[task.Meta.Id].Execution; //运行配置上的状态引用更新到任务上 //Note:序列化时将状态置为默认,因为有些异常会奖Runing记下使得该任务再也无法运行了。 task.Execution.RunStatus = TaskRunStatusType.Default; } task.Execution.IsExsit = true; } ////更新已移除的任务状态 //foreach (var job in _execution.Tasks) //{ // if (!job.Execution.IsExsit) // { // job.Execution.RunStatus = TaskRunStatusType.Removing; // } //} //Save(); logRun.DebugFormat("任务配置实例化完成。"); _instance.Execution = _execution; }
/// <summary> /// 应用程序入口 /// </summary> /// <param name="args"></param> public static void Main(string[] args) { log.DebugFormat("args:[{0}]", string.Join(" ", args)); try { var newMutexCreated = false; //var reg = new Regex("[^A-Za-z0-9_]", RegexOptions.Compiled); //移去非字符数字的字符 var mutexName = Md5.Encrypt( $"{AppDomain.CurrentDomain.BaseDirectory}-{Assembly.GetExecutingAssembly().GetName().FullName}"); //唯一的名称 try { var obj = new Mutex(false, mutexName, out newMutexCreated); } catch (Exception ex) { log.Error($"创建互斥体[mutexName = {mutexName}]异常,程序退出", ex); Environment.Exit(1); } if (newMutexCreated) { log.DebugFormat("创建互斥体[mutexName = {0}]成功,开始创建服务", mutexName); //无参数时直接运行服务 if ((!Environment.UserInteractive)) { log.DebugFormat("RunAsService"); RunAsService(); return; } if (args != null && args.Length > 0) { if (args[0].Equals("-i", StringComparison.OrdinalIgnoreCase)) { log.InfoFormat("Install the service..."); SelfInstaller.InstallMe(); return; } if (args[0].Equals("-u", StringComparison.OrdinalIgnoreCase)) { log.InfoFormat("Uninstall the service..."); SelfInstaller.UninstallMe(); return; } if (args[0].Equals("-t", StringComparison.OrdinalIgnoreCase) || args[0].Equals("-c", StringComparison.OrdinalIgnoreCase)) { log.InfoFormat("Run as Console.[{0}]", Assembly.GetExecutingAssembly().Location); RunAsConsole(args); return; } const string tip = "Invalid argument! note:\r\n -i is install the service.;\r\n -u is uninstall the service.;\r\n -t or -c is run the service on console."; log.DebugFormat(tip); Console.WriteLine(tip); Console.ReadLine(); } else { #if DEBUG log.InfoFormat("Run as Console.[{0}]", Assembly.GetExecutingAssembly().Location); RunAsConsole(args); #endif } } else { log.Error("有一个实例正在运行,如要调试,请先停止其它正在运行的实例如WindowsService,程序退出。"); Environment.Exit(1); } } catch (Exception ex) { log.Error("启动服务异常", ex); //throw; } }