/// <summary> /// 暂停 /// </summary> public void Pause() { lock (this) { ChangeStatus(TaskRunStatus.Pausing); TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //禁止再次回调 ChangeStatus(TaskRunStatus.Paused); Logger.Debug("[{0}]暂停,计时器已暂停。(最后一次回调的任务可能还在执行)", this); } }
private void StopTask() { lock (this) { ChangeStatus(TaskRunStatus.Stoping); TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //禁止再次回调 Task.Execution.RunStatus = TaskRunStatus.Stoped; ChangeStatus(TaskRunStatus.Stoped); Logger.Debug("[{0}] 停止,计时器已释放。", this); } }
/// <summary> /// 暂停 /// </summary> public void Pause() { lock (this) { ChangeStatus(TaskRunStatusType.Pausing); //SaveExecution(); //先保存一次状态 TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //禁止再次回调 ChangeStatus(TaskRunStatusType.Paused); Log.Debug($"[{this}]暂停,计时器已暂停。(最后一次回调的任务可能还在执行)"); } }
private void StopTask() { lock (this) { ChangeStatus(TaskRunStatusType.Stoping); TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //禁止再次回调 //SaveExecution(); //先保存一次状态 Task.Execution.RunStatus = TaskRunStatusType.Stoped; ChangeStatus(TaskRunStatusType.Stoped); Log.Debug($"[{this}] 停止,计时器已释放。"); } }
/// <summary> /// 恢复 /// </summary> public void Resume() { lock (this) { ChangeStatus(TaskRunStatus.Running); var now = SystemTime.Now(); var nextRun = Task.GetNextRunTime(now); if (nextRun == null) { Logger.Warn("[{0}] 无法恢复,因为下次执行时间为null", this); return; } var dueTime = nextRun.Value.Subtract(now); TaskWorker.Change(dueTime /*第一次延时调用*/, TimeSpan.FromMilliseconds(-1) /*Note:回调时会更改调用延时,此周期设为无限*/); //重启计时器 Logger.Debug("[{0}] 暂停,计时器已恢复。(最后一次回调的任务可能还在执行)", this); } }
/// <summary> /// 恢复 /// </summary> public void Resume() { lock (this) { ChangeStatus(TaskRunStatusType.Running); var now = SystemTime.Now(); var nextRun = Task.GetNextRunTime(now); if (nextRun == null) { Log.Warn($"[{this}] 无法恢复,因为下次执行时间为null"); return; } var dueTime = nextRun.Value.Subtract(now); TaskWorker.Change(dueTime /*第一次延时调用*/, TimeSpan.MaxValue); //重启计时器 Log.Debug($"[{this}] 暂停,计时器已恢复。(最后一次回调的任务可能还在执行)"); } }
/// <summary> /// 工作运行 /// Note:两次间隔有100毫秒左右的误差 /// </summary> public virtual void Working() { try { // http://www.cnblogs.com/SharkBin/archive/2012/08/04/2622627.html TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //暂停计时。 if (IsRemoving) { Logger.Warn("任务被标起为移除,回调中断,且任务不会被再次调用。"); return; } //执行今日任务 _runTimes++; var now = SystemTime.Now(); Logger.Info("[{0}] 第{1}次执行开始。[{2}] ◇", this, _runTimes, now.ToShortTimeString()); ChangeStatus(TaskRunStatus.Working); var val = new TaskResult(); try { val = WorkHandler(); //同步委托,任务执行[可能较耗时] } catch (Exception ex) { Logger.Error("执行任务<{0}>时发生异常:{1}", this.Task, ex); val.Result = TaskResultType.Error; val.ExtendMessage = ex.Message; } finally { ChangeStatus(TaskRunStatus.Worked); Task.Execution.LastRun = now; } var runSpan = SystemTime.Now() - now; Logger.Info("[{0}] 第{1}次执行结果[{2} : {3}] [Execution:{4}]", this, _runTimes, val.Result, val.Message, runSpan); //Note:工作完成后的状态处理 //Note:注意,这里的错误次数实际上是执行失败的次数 if (val.Result.HasFlag(TaskResultType.Error)) { var sleepInterval = ((TimeSpan)Task.WorkSetting.SleepInterval); Task.Execution.SleepTimes++; Logger.Warn("[{0}] 状态更新[{1}],休眠次数++ ,准备[{2}]后再次执行", this, val.Result, sleepInterval); TaskWorker.Change(sleepInterval, TimeSpan.FromMilliseconds(-1)); return; } else { Task.Execution.RunTimes++; var runInterval = Task.GetNextInterval(); if (runInterval == null) { ChangeStatus(TaskRunStatus.Removing); Logger.Debug("[{0}] 下次运行时间为null,当前任务停止。", this); return; } if (runInterval.Value.TotalMilliseconds > WorkerInterval * 5) { ChangeStatus(TaskRunStatus.Removing); Logger.Debug("[{0}] 下次运行时间{1},超过5倍工作线程间隔,暂时移除执行队列。当前任务停止。", this, runInterval); return; } //var runInterval = runTime.Value.Subtract(now); SaveExecution(); Logger.Debug("[{0}]第{1}次执行结束。 运行成功[Times:{2}] ,准备[{3}]后再次执行 ◆", this, _runTimes, Task.Execution.RunTimes, runInterval); TaskWorker.Change(runInterval.Value, TimeSpan.FromMilliseconds(-1)); //Note:更改计时器约50多毫秒 } #region 根据任务配置做出相应动作 //本次任务已完成,Note:只有本次任务达到所设条件才算是正常完成,正常完成后才更新最后成功完成的时间。 if ((Task.Execution.RunTimes >= Task.WorkSetting.Times && Task.WorkSetting.Times > 0) || (val.Result.HasFlag(TaskResultType.Finished))) { ChangeStatus(TaskRunStatus.Removing); Logger.Debug("■ [{0}] ({1})完成。■", this, Task.Execution.LastSucceedRun); return; } //根据设定,一旦有错误发生。立即停止 if (val.Result.HasFlag(TaskResultType.Error) && Task.WorkSetting.ErrorWay == ErrorWayType.Stop) { ChangeStatus(TaskRunStatus.Removing); Logger.Info("▲ [{0}] 根据设定Stop,发生了错误一次,等待移除。▲", this); return; } //根据设定,有错误时。休眠超期后停止 if (Task.Execution.SleepTimes >= Task.WorkSetting.SleepInterval.Times && Task.WorkSetting.SleepInterval.Times > 0 && Task.WorkSetting.ErrorWay == ErrorWayType.TryAndStop) { ChangeStatus(TaskRunStatus.Removing); Logger.Info("▲ [{0}] 根据设定Sleep,发生了错误{Task.Execution.SleepTimes}次,等待移除。▲", this); return; } #endregion } catch (Exception ex) { //Note:异常发生后停止该任务,不管任何原因 Logger.Error("[{0}] 执行异常,停止执行。{1}", this, ex); Stop(); } finally { } }
/// <summary> /// 工作运行 /// Note:两次间隔有100豪秒左右的误差 /// </summary> public virtual void Working() { try { TaskWorker.Change(Timeout.Infinite, Timeout.Infinite); //暂停计时。 if (IsRemoving) { Log.Warn("任务被标起为移除,回调中断,且任务不会被再次调用。"); return; } //执行今日任务 _runTimes++; var now = SystemTime.Now(); //Log.Info($"[{this}] 第{_runTimes}次执行开始。[{now:HH:mm:ss ffff}] ◇"); ChangeStatus(TaskRunStatusType.Working); var val = new TaskResult(); try { val = WorkHandler(); //同步委托,任务执行[可能较耗时] } catch (Exception ex) { Log.Error(ex, $"执行任务<{Task}>时发生异常:"); //throw; val.Result = TaskResultType.Error; val.Message = ex.Message; } finally { ChangeStatus(TaskRunStatusType.Worked); Task.Execution.LastRun = now; } var runSpan = SystemTime.Now() - now; Log.Info($"[{this}] 第 {_runTimes} 次执行,结果 [{val.Result} : {val.Message}] [RuningTime:{runSpan}]"); //Note:工作完成后的状态处理 //Note:注意,这里的错误次数实际上是执行失败的次数 if (val.Result.HasFlag(TaskResultType.Error)) { var sleepInterval = ((TimeSpan)Task.WorkSetting.SleepInterval); Task.Execution.SleepTimes++; Log.Warn($"[{this}] 状态更新[{val.Result}],休眠次数++ ,准备[{sleepInterval}]后再次执行"); TaskWorker.Change(sleepInterval, TimeSpan.FromMilliseconds(-1)); return; } else { Task.Execution.RunTimes++; var runInterval = Task.GetNextInterval(); if (runInterval == null) { ChangeStatus(TaskRunStatusType.Removing); Log.Debug($"[{this}] 下次运行时间为null,当前任务停止。"); return; } if (runInterval.Value.TotalMilliseconds > WorkerInterval * 3) { ChangeStatus(TaskRunStatusType.Removing); Log.Debug($"[{this}] 下次运行时间{runInterval},超过3倍工作线程间隔,暂时移除执行队列。当前任务停止。"); return; } //var runInterval = runTime.Value.Subtract(now); SaveExecution(); Log.Debug($"[{this}]第{_runTimes}次执行结束。 运行成功[Times:{Task.Execution.RunTimes}] ,准备[{runInterval}]后再次执行 ◆"); TaskWorker.Change(runInterval.Value, TimeSpan.FromMilliseconds(-1)); //Note:更改计时器约50多毫秒 } #region 根据任务配置做出相应动作 //本次任务已完成,Note:只有本次任务达到所设条件才算是正常完成,正常完成后才更新最后成功完成的时间。 if ((Task.Execution.RunTimes >= Task.WorkSetting.Times && Task.WorkSetting.Times > 0) || (val.Result.HasFlag(TaskResultType.Finished))) { //Task.Meta.Execution.LastSucceedRun = PathDate ?? now; //Note:可自动补全点 //Task.Meta.Execution.RunStatus = TaskRunStatusType.TodayComplete; ChangeStatus(TaskRunStatusType.Removing); Log.Debug($"■ [{this}] ({Task.Execution.LastSucceedRun})完成。■"); return; } //根据设定,一旦有错误发生。立即停止 if (val.Result.HasFlag(TaskResultType.Error) && Task.WorkSetting.ErrorWay == ErrorWayType.Stop) { ChangeStatus(TaskRunStatusType.Removing); Log.Info($"▲ [{this}] 根据设定Stop,发生了错误一次,等待移除。▲"); return; } //根据设定,有错误时。休眠超期后停止 if (Task.Execution.SleepTimes >= Task.WorkSetting.SleepInterval.Times && Task.WorkSetting.SleepInterval.Times > 0 && Task.WorkSetting.ErrorWay == ErrorWayType.TryAndStop) { ChangeStatus(TaskRunStatusType.Removing); Log.Info($"▲ [{this}] 根据设定Sleep,发生了错误{Task.Execution.SleepTimes}次,等待移除。▲"); return; } #endregion } catch (Exception ex) { //Note:异常发生后停止该任务,不管任何原因 Log.Error(ex, $"[{this}] 执行异常,停止执行。"); Stop(); //throw; } finally { } }