// 初始化阶段探测本地读者缓存数据是否存在,如果不存在则设法启动首次读者同步 public static void DetectPatronLocalDatabase() { if (PatronReplication.PatronDataExists() == false) { SaveStartDate(null); } }
// 启动一般监控任务 public static void StartMonitorTask() { if (_monitorTask != null) { return; } PerdayTask.StartPerdayTask(); CancellationToken token = _cancel.Token; // bool download_complete = false; token.Register(() => { _eventMonitor.Set(); }); _monitorTask = Task.Factory.StartNew(async() => { WpfClientInfo.WriteInfoLog("书柜监控专用线程开始"); try { while (token.IsCancellationRequested == false) { // await Task.Delay(TimeSpan.FromSeconds(10)); _eventMonitor.WaitOne(_monitorIdleLength); token.ThrowIfCancellationRequested(); // *** // 关闭天线射频 if (_tagAdded) { _ = Task.Run(async() => { try { await SelectAntennaAsync(); } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}"); } }); _tagAdded = false; } if (DateTime.Now - _lastDetectTime > _detectPeriod) { DetectLibraryNetwork(); _lastDetectTime = DateTime.Now; } // 提醒关门 WarningCloseDoor(); // 下载或同步读者信息 string startDate = LoadStartDate(); if (/*download_complete == false || */ string.IsNullOrEmpty(startDate) && _replicatePatronError == 0) { // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步 if (string.IsNullOrEmpty(startDate)) { // SaveStartDate(""); var repl_result = await PatronReplication.DownloadAllPatronRecordAsync( (text) => { WpfClientInfo.WriteInfoLog(text); PageShelf.TrySetMessage(null, text); }, token); if (repl_result.Value == -1) { // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载 _replicatePatronError++; } else { SaveStartDate(repl_result.StartDate); } // 立刻允许接着做一次零星同步 ActivateMonitor(); } // download_complete = true; } else { // 进行零星同步 if (DateTime.Now - _lastReplicateTime > _replicatePeriod) { // string startDate = LoadStartDate(); // testing // startDate = "20200507:0-"; if (string.IsNullOrEmpty(startDate) == false) { string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now); // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 ReplicationResult repl_result = await PatronReplication.DoReplication( startDate, endDate, LogType.OperLog, token); if (repl_result.Value == -1) { WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}"); } else if (repl_result.Value == 1) { string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-"; // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了 SaveStartDate(lastDate); } _lastReplicateTime = DateTime.Now; } } } } _monitorTask = null; } catch (OperationCanceledException) { } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"书柜监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}"); App.SetError("shelf_monitor", $"书柜监控专用线程出现异常: {ex.Message}"); } finally { WpfClientInfo.WriteInfoLog("书柜监控专用线程结束"); } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
// 启动一般监控任务 public static void StartMonitorTask() { if (_monitorTask != null) { return; } CancellationToken token = _cancel.Token; bool download_complete = false; token.Register(() => { _eventMonitor.Set(); }); _monitorTask = Task.Factory.StartNew(async() => { WpfClientInfo.WriteInfoLog("监控专用线程开始"); try { while (token.IsCancellationRequested == false) { // await Task.Delay(TimeSpan.FromSeconds(10)); _eventMonitor.WaitOne(_monitorIdleLength); token.ThrowIfCancellationRequested(); // *** // 关闭天线射频 if (_tagAdded) { _ = Task.Run(async() => { try { await SelectAntennaAsync(); } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}"); } }); _tagAdded = false; } if (DateTime.Now - _lastDetectTime > _detectPeriod) { DetectLibraryNetwork(); _lastDetectTime = DateTime.Now; } // 提醒关门 WarningCloseDoor(); // 下载或同步读者信息 string startDate = LoadStartDate(); if (/*download_complete == false || */ string.IsNullOrEmpty(startDate)) { // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步 if (string.IsNullOrEmpty(startDate)) { // SaveStartDate(""); var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(token); if (repl_result.Value == -1) { // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载 } else { SaveStartDate(repl_result.StartDate); } // 立刻允许接着做一次零星同步 ActivateMonitor(); } // download_complete = true; } else { // 进行零星同步 if (DateTime.Now - _lastReplicateTime > _replicatePeriod) { // string startDate = LoadStartDate(); // testing // startDate = "20200507:0-"; if (string.IsNullOrEmpty(startDate) == false) { string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now); // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 ReplicationResult repl_result = PatronReplication.DoReplication( startDate, endDate, LogType.OperLog, token); if (repl_result.Value == -1) { WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}"); } else if (repl_result.Value == 1) { string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-"; // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了 SaveStartDate(lastDate); } _lastReplicateTime = DateTime.Now; } } } // 检查升级 dp2ssl if (_updated == false // && StringUtil.IsDevelopMode() == false && ApplicationDeployment.IsNetworkDeployed == false && DateTime.Now - _lastUpdateTime > _updatePeriod) { WpfClientInfo.WriteInfoLog("开始自动检查升级"); // result.Value: // -1 出错 // 0 经过检查发现没有必要升级 // 1 成功 // 2 成功,但需要立即重新启动计算机才能让复制的文件生效 var update_result = await GreenInstaller.InstallFromWeb("http://dp2003.com/dp2ssl/v1_dev", "c:\\dp2ssl", "delayExtract,updateGreenSetupExe", //true, //true, token, null); if (update_result.Value == -1) { WpfClientInfo.WriteErrorLog($"自动检查升级出错: {update_result.ErrorInfo}"); } else { WpfClientInfo.WriteInfoLog($"结束自动检查升级 update_result:{update_result.ToString()}"); } if (update_result.Value == 1 || update_result.Value == 2) { App.TriggerUpdated("重启可使用新版本"); _updated = true; PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启时可自动升级到新版本"); } _lastUpdateTime = DateTime.Now; } } _monitorTask = null; } catch (OperationCanceledException) { } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}"); App.SetError("monitor", $"监控专用线程出现异常: {ex.Message}"); } finally { WpfClientInfo.WriteInfoLog("监控专用线程结束"); } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
// 按照命令启动一个批处理任务(不是自动启动) // return: // -1 出错 // 0 启动成功 // 1 调用前任务已经处于执行状态,本次调用激活了这个任务 public int StartBatchTask(string strName, BatchTaskInfo param, out BatchTaskInfo info, out string strError) { strError = ""; info = null; if (strName == "!continue") { this.PauseBatchTask = false; // 2016/11/6 if (this.BatchTasks == null) { strError = "this.BatchTasks == null"; return(-1); } // 2013/11/23 foreach (BatchTask current_task in this.BatchTasks) { current_task.Activate(); } info = GetTaskInfo("全部批处理任务已经解除暂停"); return(1); } // 2007/12/18 if (this.ContainsHangup("LogRecover") == true) { strError = "当前系统正处在LogRecover挂起状态,无法启动新的批处理任务"; return(-1); } // 2012/2/4 if (this.PauseBatchTask == true) { strError = "当前所有批处理任务均处在暂停状态,无法启动新的批处理任务"; return(-1); } if (this.BatchTasks == null) { strError = "this.BatchTasks == null"; return(-1); } BatchTask task = this.BatchTasks.GetBatchTask(strName); // 创建新的任务 if (task == null) { if (strName == "预约到书管理") { task = new ArriveMonitor(this, strName); } else if (strName == "日志恢复") { task = new OperLogRecover(this, strName); } else if (strName == "dp2Library 同步") { task = new LibraryReplication(this, strName); } else if (strName == "重建检索点") { task = new RebuildKeys(this, strName); } /* * else if (strName == "跟踪DTLP数据库") * task = new TraceDTLP(this, strName); * */ else if (strName == "正元一卡通读者信息同步") { task = new ZhengyuanReplication(this, strName); } else if (strName == "迪科远望一卡通读者信息同步") { task = new DkywReplication(this, strName); } else if (strName == "读者信息同步") { task = new PatronReplication(this, strName); } else if (strName == "超期通知") { task = new ReadersMonitor(this, strName); } else if (strName == "消息监控") { task = new MessageMonitor(this, strName); } else if (strName == "创建 MongoDB 日志库") { task = new BuildMongoOperDatabase(this, strName); } else { strError = "系统不能识别任务名 '" + strName + "'"; return(-1); } try { this.BatchTasks.Add(task); } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return(-1); } } else { bool bOldStoppedValue = task.Stopped; if (bOldStoppedValue == false) { if (strName == "重建检索点") { task.StartInfos.Add(param.StartInfo); task.AppendResultText("新任务已加入等待队列:\r\n---\r\n" + RebuildKeys.GetSummary(param.StartInfo) + "\r\n---\r\n\r\n"); } else { // 尽量采用前端发来的参数进行运行 task.StartInfo = param.StartInfo; } // 激活 2007/10/10 task.eventActive.Set(); task.ManualStart = true; // 表示为命令启动 strError = "任务 " + task.Name + " 已经在运行中,不能重复启动。本次操作激活了这个任务。"; return(1); } } // 执行日志恢复任务前,需要先中断正在执行的其他任何任务 // TODO: 日志恢复 任务结束后,原先中断的那些任务并不会自动去启动。需要系统管理员手动重新启动一次Application if (strName == "日志恢复") { StopAllBatchTasks(); } task.ManualStart = true; // 表示为命令启动 task.StartInfo = param.StartInfo; task.ClearProgressFile(); // 清除进度文件内容 task.StartWorkerThread(); /* * // 激活 2007/10/10 * task.eventActive.Set(); * */ info = task.GetCurrentInfo(param.ResultOffset, param.MaxResultBytes); return(0); }
// 按照命令启动一个批处理任务(不是自动启动) // return: // -1 出错 // 0 启动成功 // 1 调用前任务已经处于执行状态,本次调用激活了这个任务 public int StartBatchTask(string strName, BatchTaskInfo param, out BatchTaskInfo info, out string strError) { strError = ""; info = null; if (strName == "!continue") { this.PauseBatchTask = false; // 2016/11/6 if (this.BatchTasks == null) { strError = "this.BatchTasks == null"; return(-1); } // 2013/11/23 foreach (BatchTask current_task in this.BatchTasks) { current_task.Activate(); } info = GetTaskInfo("全部批处理任务已经解除暂停"); return(1); } // 2007/12/18 if (this.ContainsHangup("LogRecover") == true) { strError = "当前系统正处在LogRecover挂起状态,无法启动新的批处理任务"; return(-1); } // 2012/2/4 if (this.PauseBatchTask == true) { strError = "当前所有批处理任务均处在暂停状态,无法启动新的批处理任务"; return(-1); } if (this.BatchTasks == null) { strError = "this.BatchTasks == null"; return(-1); } BatchTask task = this.BatchTasks.GetBatchTask(strName); // 创建新的任务 if (task == null) { if (strName == "预约到书管理") { task = new ArriveMonitor(this, strName); } else if (strName == "日志恢复") { task = new OperLogRecover(this, strName); } else if (strName == "dp2Library 同步") { // task = new LibraryReplication(this, strName); strError = "尚未正式提供服务"; // 2017/6/8 return(-1); } else if (strName == "重建检索点") { task = new RebuildKeys(this, strName); } /* * else if (strName == "跟踪DTLP数据库") * task = new TraceDTLP(this, strName); * */ else if (strName == "正元一卡通读者信息同步") { task = new ZhengyuanReplication(this, strName); } else if (strName == "迪科远望一卡通读者信息同步") { task = new DkywReplication(this, strName); } else if (strName == "读者信息同步") { task = new PatronReplication(this, strName); } else if (strName == "超期通知") { task = new ReadersMonitor(this, strName); } else if (strName == "消息监控") { task = new MessageMonitor(this, strName); } else if (strName == "创建 MongoDB 日志库") { task = new BuildMongoOperDatabase(this, strName); } else if (strName == "服务器同步") { task = new ServerReplication(this, strName); } else if (strName == "大备份") { task = new BackupTask(this, strName); } else { strError = "系统不能识别任务名 '" + strName + "'"; return(-1); } try { this.BatchTasks.Add(task); } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return(-1); } } else { bool bOldStoppedValue = task.Stopped; if (bOldStoppedValue == false) { if (strName == "重建检索点") { task.StartInfos.Add(param.StartInfo); task.AppendResultText("新任务已加入等待队列:\r\n---\r\n" + RebuildKeys.GetSummary(param.StartInfo) + "\r\n---\r\n\r\n"); } else { // 尽量采用前端发来的参数进行运行 task.StartInfo = param.StartInfo; } // 激活 2007/10/10 task.eventActive.Set(); task.ManualStart = true; // 表示为命令启动 int nRet = WaitForBegin( task, strName, param, ref info, out string strError1); if (nRet == 0) { strError = "任务 " + task.Name + " 已经在运行中,不能重复启动。本次操作激活了这个任务。"; return(1); } strError += "; " + strError1; return(1); } } // 执行日志恢复任务前,需要先中断正在执行的其他任何任务 // TODO: 日志恢复 任务结束后,原先中断的那些任务并不会自动去启动。需要系统管理员手动重新启动一次Application if (strName == "日志恢复") { StopAllBatchTasks(); } task.SetProgressText(""); task.ManualStart = true; // 表示为命令启动 task.StartInfo = param.StartInfo; task.ClearProgressFile(); // 清除进度文件内容 task.StartWorkerThread(); /* * // 激活 2007/10/10 * task.eventActive.Set(); * */ return(WaitForBegin( task, strName, param, ref info, out strError)); #if NO // 等待工作线程运行到启动点 if (task.StartInfo.WaitForBegin) { if (task.eventStarted.WaitOne(TimeSpan.FromSeconds(10)) == false) { strError = "任务 " + task.Name + " 未能在 10 秒内启动成功"; return(1); } // 2017/8/23 if (string.IsNullOrEmpty(task.ErrorInfo) == false) { strError = "任务 " + task.Name + " 启动阶段出错: " + task.ErrorInfo; return(1); } } info = task.GetCurrentInfo(param.ResultOffset, param.MaxResultBytes); if (task.StartInfo.WaitForBegin) { if (info.StartInfo == null) { info.StartInfo = new BatchTaskStartInfo(); } if (strName == "大备份") { BackupTask temp = task as BackupTask; info.StartInfo.OutputParam = temp.OutputFileNames; } } return(0); #endif }