/// <summary> /// The main function of the worker, creates the Task instance and run it /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void worker_DoWork(object sender, DoWorkEventArgs e) { //Task runningTask = e.Argument as Task; TaskRunning = true; var failed = false; while (QueueList.Count != 0) { var runningTask = QueueList.First(); RunningTask = runningTask; var startTime = DateTime.Now; try { (sender as BackgroundWorker).ReportProgress(0, new KeyValuePair <Task, string>(runningTask, "")); var taskGenerator = Activator.CreateInstance(Type.GetType(runningTask.GeneratorType)) as GeneratorBase; taskGenerator.Log += Add_Message; taskGenerator.Result += Add_Result; taskGenerator.Props += Add_Prop; taskGenerator.StartGenerator(); (sender as BackgroundWorker).ReportProgress(1, new KeyValuePair <Task, string>(runningTask, "")); } catch (Exception ex) { var messageBuilder = new StringBuilder(); #if DEBUG // In debug mode shows everything if (ex.InnerException != null) { messageBuilder.Append("INNER ERROR MESSAGE:\r\n-------------------------------\r\n\r\n"); messageBuilder.Append(ex.InnerException.Message); messageBuilder.Append("\r\n\r\nINNER STACK TRACE:\r\n-------------------------------\r\n\r\n"); messageBuilder.Append(ex.InnerException.StackTrace); messageBuilder.Append("\r\n\r\n"); } messageBuilder.Append("ERROR MESSAGE:\r\n-------------------------------\r\n\r\n"); messageBuilder.Append(ex.Message); messageBuilder.Append("\r\n\r\nSTACK TRACE:\r\n-------------------------------\r\n\r\n"); messageBuilder.Append(ex.StackTrace); #else // In release just shows the exception message messageBuilder.Append(ex.Message); #endif (sender as BackgroundWorker).ReportProgress(-1, new KeyValuePair <Task, string>(runningTask, messageBuilder.ToString())); failed = true; } finally { _lastResult = failed ? TaskResult.Fail : TaskResult.Success; var endTime = DateTime.Now; var finishedTaskId = QueueList[0].Id; e.Result = new Run { Date = DateTime.Now, Duration = (int)(endTime - startTime).TotalSeconds, Result = _lastResult, TaskId = finishedTaskId, UserId = CurrentUser.Id }; PrintMessage(String.Format("[{0}] {1} in {2:mm\\mss\\sff}", QueueList[0].Name, _lastResult, (endTime - startTime))); // If scheduled task see if failed // so it need to be reschedule X minutes later Y times if (CurrentlyScheduledTasks.ContainsKey(finishedTaskId)) { if (_lastResult == TaskResult.Success) { CurrentlyScheduledTasks.Remove(finishedTaskId); PrintMessage(String.Format("[Scheduler] {0} ran successfully, no retries are scheduled.", QueueList[0].Name)); } else { CurrentlyScheduledTasks[finishedTaskId].Retry -= 1; if (CurrentlyScheduledTasks[finishedTaskId].Retry == 0) { CurrentlyScheduledTasks.Remove(finishedTaskId); PrintMessage(String.Format("[Scheduler] {0} task failed, no re-run will be attempted.", QueueList[0].Name), Logger.LogType.Warning); } else { CurrentlyScheduledTasks[finishedTaskId].ScheduleTime = CurrentlyScheduledTasks[finishedTaskId].ScheduleTime.Add(new TimeSpan(0, CurrentlyScheduledTasks[finishedTaskId].Interval, 0)); PrintMessage(String.Format("[Scheduler] {0} task failed, the task will re-run automatically in {1} minutes", QueueList[0].Name, CurrentlyScheduledTasks[finishedTaskId].Interval), Logger.LogType.Warning); } } } // Refresh Queue list var newQueueTasks = new ObservableCollection <Task>(QueueList); newQueueTasks.RemoveAt(0); QueueList = newQueueTasks; } } TaskRunning = false; }
/// <summary> /// Function launched every Tick (every minute) to see if some task /// was scheduled and need to be run /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void LaunchScheduleTimer_Tick(object sender, EventArgs e) { // First looking for schedule tasks already ran but failed and need to re-run foreach (var toAdd in from schedule in CurrentlyScheduledTasks where schedule.Value.ScheduleTime.Hour == DateTime.Now.Hour && schedule.Value.ScheduleTime.Minute == DateTime.Now.Minute select new { toScheduleTask = TaskManager.GetTaskById(schedule.Key, RunTimeContext.Context.DatabaseContext), taskSchedule = schedule.Value } ) { SelectedTask = toAdd.toScheduleTask; QueueList.Add(toAdd.toScheduleTask); if (!TaskRunning) { Start(); } } // Now looking for task to add in the CurrentlyScheduledTasks list and run them foreach (var toAdd in from schedule in ScheduledList where schedule.Date.Hour == DateTime.Now.Hour && schedule.Date.Minute == DateTime.Now.Minute select new { toScheduleTask = TaskManager.GetTaskById(schedule.TaskId, RunTimeContext.Context.DatabaseContext), taskSchedule = schedule } ) { if (string.IsNullOrEmpty(toAdd.taskSchedule.DayOfWeek)) { toAdd.taskSchedule.DayOfWeek = string.Empty; } int dayOfWeekSign = 0;//schedule时间是否符合设定的week时间的标志位 string[] dayString = toAdd.taskSchedule.DayOfWeek.Split(','); string nowDayOfWeek = DateTime.Now.DayOfWeek.ToString(); nowDayOfWeek = nowDayOfWeek.Substring(0, 3); if (dayString.Length == 1 && string.IsNullOrEmpty(dayString[0])) { dayOfWeekSign = 1; } foreach (string item in dayString) { if (nowDayOfWeek.Equals(item)) { dayOfWeekSign = 1; break; } } if (dayOfWeekSign == 0) { break; } SelectedTask = toAdd.toScheduleTask; CurrentlyScheduledTasks.Add(toAdd.toScheduleTask.Id, new ScheduledTaskInfo { Interval = toAdd.taskSchedule.Interval.Value, Retry = toAdd.taskSchedule.Count.Value, ScheduleTime = toAdd.taskSchedule.Date }); PrintMessage(String.Format("[Scheduler] {0} is scheduled to run at {1:HH:mm tt}, adding to queue now", toAdd.toScheduleTask.Name, toAdd.taskSchedule.Date)); QueueList.Add(toAdd.toScheduleTask); if (!TaskRunning) { Start(); } } }