public void AddTask(string taskName, TimeSpan initialInterval, Func <Task <TimeSpan> > tick) { TimeSchedulerTask task = new TimeSchedulerTask(taskName, initialInterval, tick); if (currentTasks.ContainsKey(task.TaskName)) { currentTasks.Remove(task.TaskName); } currentTasks.Add(task.TaskName, task); }
// // This is the main method in our thread - it looks to see which timers // should be fired waiting a short while between each one.... /// /// private void TimeSchedulerRunner() { LogMessage("Scheduler thread is running"); bool workDone = false; while (timerRunning_) { try { if (workDone == false) { Task.Delay(TimeSpan.FromSeconds(2)).Wait(); // We wait two seconds.... } else { workDone = false; } long nowInSeconds = DateTime.UtcNow.Ticks / TimeSpan.TicksPerSecond; TimeSchedulerTask task = GetNextTask(); if (task != null) { LogMessage("Checking time on task " + task.TaskName + " taskStartTime=" + task.TaskStartTime + " now=" + nowInSeconds); if (task.TaskStartTime <= nowInSeconds) { workDone = true; LogMessage("About to execute task " + task.TaskName); currentTasks.Remove(task.TaskName); // Remove task from list - we are about to execute it... // Ok....we should be running this task now... Task <TimeSpan> func = task.InvokeFunction.Invoke(); if (func != null) { func.Wait(); if (func.IsFaulted) { LogMessage("Task " + task.TaskName + " faulted=" + func.Exception.Message + " stack=" + func.Exception.StackTrace); } // // Now we need to re-schedule it.... // if (!func.Result.Equals(STOP_TIMER)) { task.SetNextStartTime(func.Result); LogMessage("Rescheduling task " + task.TaskName + " for " + task.TaskStartTime); currentTasks.Add(task.TaskName, task); // Put back onto queue for next time.... } } else { LogMessage("task " + task.TaskName + " returned null - will not be re-scheduled"); } } } } catch (Exception e) { LogMessage("Runner has errored - " + e.Message); LogMessage("Stack=" + e.StackTrace); if (e.InnerException != null) { LogMessage("InnerException=" + e.InnerException.StackTrace); } } } }