// // // **** TryGetNextUnsuccessfulChild() **** /// <summary> /// This returns the latest child in the list that is NOT a success, or /// it returns the last child regardless. /// </summary> /// <param name="currentChild"></param> /// <returns>True, if currentChild is not null</returns> public bool TryGetNextUnsuccessfulChild(out TaskEventArg currentChild) { currentChild = null; if (m_Children == null || m_Children.Count == 0) { return(false); } int n = 0; while (n < m_Children.Count && currentChild == null) // its the first event that is not "sucessful" { TaskEventArg child = (TaskEventArg)m_Children[n]; if (child.Status != TaskStatus.Success) // look for first child that is not completed! { currentChild = child; // If found, he is the current working task } n++; } if (currentChild == null) { currentChild = m_Children[m_Children.Count - 1]; // return last child at least. } // Exit. return(true); }//TryGetCurrentChild()
public override void RequestStop() { TaskEventArg request = new TaskEventArg(); request.RequestStop = true; this.HubEventEnqueue(request); }
public bool TryToAddChild(TaskEventArg newChild) { if (m_Children == null) { m_Children = new List <TaskEventArg>(); } if (m_Children.Contains(newChild)) { return(false); } m_Children.Add(newChild); newChild.m_Parent = this; return(true); }// TryToAddChild()
// // private void OnTaskCompleted(TaskEventArg completedTask) { Log.NewEntry(LogLevel.Minor, "OnTaskCompleted: {0}", completedTask); if (m_WaitingTasks.Contains(completedTask)) { Log.NewEntry(LogLevel.Minor, "OnTaskCompleted: Removing from wait list.", completedTask); m_WaitingTasks.Remove(completedTask); } if (TaskCompleted != null) { TaskCompleted(this, completedTask); } }
public bool TryGetParent(out TaskEventArg parent) { parent = m_Parent; return(parent != null); }
public bool IsParentOf(TaskEventArg possibleChild) { return(this.m_Children != null && this.m_Children.Contains(possibleChild)); }
}// HubEventHandler() // // // ***************************************************** // **** ProcessTask() **** // ***************************************************** /// <summary> /// Processes tasks from user. /// </summary> private void ProcessTask(TaskEventArg eventArg) { bool triggerTaskCompletedEvent = false; // Process multiple tasks if (eventArg.IsParent()) // This task has children to be completed in sequence. { TaskEventArg currentWorkingRequest = null; // the child-request that we are currently working on. if (eventArg.TryGetNextUnsuccessfulChild(out currentWorkingRequest)) { eventArg.Status = TaskStatus.ContinueWorking; // set parent as "working" if (currentWorkingRequest.Status == TaskStatus.Success) // Usually, the "current" child is not finished successfully, { // but if its the last child, then it signals the end of the task. eventArg.Status = TaskStatus.Success; // Mark parent for success... triggerTaskCompletedEvent = true; } else if (currentWorkingRequest.Status == TaskStatus.Failed) // the last non-successful child says its failed... { eventArg.Status = TaskStatus.Failed; // done. Failed request triggerTaskCompletedEvent = true; } else if (DateTime.Now.CompareTo(eventArg.StartTime) >= 0) { // We are passed the start time, submit request. Log.BeginEntry(LogLevel.Minor, "ProcessTask: {0} ", eventArg); Log.AppendEntry(" ----> {0}", currentWorkingRequest); // output the current child to work. Log.EndEntry(); ProcessTask(currentWorkingRequest); // continue trying to work this task. } else { // We are working on a child task, but not past start time yet. Log.NewEntry(LogLevel.Minor, "ProcessTask: Waiting to start {0}. ", eventArg); if (!m_WaitingTasks.Contains(eventArg)) // make sure that we will revist this parent event again... { m_WaitingTasks.Add(eventArg); } } } } else if (eventArg.RequestStop) { if (DateTime.Now.CompareTo(eventArg.StartTime) >= 0) { Log.NewEntry(LogLevel.Major, "ProcessTask: {0} ----> Stop requested.", eventArg); if (m_Timer != null) { m_Timer.Stop(); m_Timer.Dispose(); m_Timer = null; } eventArg.Status = TaskStatus.Success; base.Stop(); } else { Log.NewEntry(LogLevel.Minor, "ProcessTask: Waiting to start {0}. ", eventArg); if (!m_WaitingTasks.Contains(eventArg)) // make sure that we will revist this parent event again... { m_WaitingTasks.Add(eventArg); } } } else { // // Process requests for task. // if (!string.IsNullOrEmpty(eventArg.EventHandlerName)) { Type thisType = this.GetType(); System.Reflection.MethodInfo[] methodInfos = thisType.GetMethods(); // Task EventHandlerName must match super-class method name! System.Reflection.MethodInfo m = null; // Method to do the task. for (int ptr = 0; ptr < methodInfos.Length; ptr++) { if (methodInfos[ptr].Name.Equals(eventArg.EventHandlerName)) { m = methodInfos[ptr]; break; // stop searching } } if (m != null) { // We found the named method to call. // We ASSUME that the implementation method will set the "Status" of the event properly! // This is critical! m.Invoke(this, new object[] { this, eventArg }); if (eventArg.Status == TaskStatus.New) { Log.NewEntry(LogLevel.Major, "ProcessTask: Method {0} has failed to change the TaskEventArg.Status field!", eventArg.EventHandlerName); Log.Flush(); eventArg.Status = TaskStatus.Failed; throw(new Exception(string.Format("Method {0}(object,EventArg) must set TaskEventArg.Status field!", eventArg.EventHandlerName))); } } else { eventArg.Status = TaskStatus.Failed; } } else { Log.NewEntry(LogLevel.Error, "ProcessTask: No eventHanderName."); eventArg.Status = TaskStatus.Failed; } // // Check final status of task // TaskEventArg parent; if (eventArg.TryGetParent(out parent)) { // This Task has a parent Task. if (eventArg.Status == TaskStatus.ContinueWorking) { // The (child) current task wants to try again. Log.NewEntry(LogLevel.Minor, "ProcessTask: {0} has parent, will wait to try again.", eventArg); if (!m_WaitingTasks.Contains(parent)) // make sure that we will revist this parent event again... { m_WaitingTasks.Add(parent); } } else { Log.NewEntry(LogLevel.Minor, "ProcessTask: {0} has parent, will flash parent.", eventArg); this.HubEventEnqueue(parent); // flash parent to continue working itself. } } else if (eventArg.Status == TaskStatus.ContinueWorking && DateTime.Now.CompareTo(eventArg.StopTime) < 0) { // This task is not complete, and is allowed to work more. if (!m_WaitingTasks.Contains(eventArg)) // make sure that we will revist this parent event again... { Log.NewEntry(LogLevel.Minor, "ProcessTask: Adding {0} to waiting queue.", eventArg); m_WaitingTasks.Add(eventArg); } else { Log.NewEntry(LogLevel.Minor, "ProcessTask: {0} already in waiting queue.", eventArg); } } else { // This task is complete, either failed, succeeded or event timed out.. whatever. triggerTaskCompletedEvent = true; } } // Exit if (triggerTaskCompletedEvent) { OnTaskCompleted(eventArg); } }//ProcessRequest()
}//TimerIntervalMinutes // #endregion//Properties #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** // // public bool AddNewTask(TaskEventArg newTask) { return(this.HubEventEnqueue(newTask)); }