/// <summary> /// The one and only method that can be used to remove a task from this queue. /// </summary> /// <remarks>Can only be called from the TastEntry itself</remarks> internal void Remove(TaskEntry entry) { LOG("Remove('" + entry + ") - Start"); ASSERT(entry != null, "Missing parameter 'entry'"); bool launchChecksAtEnd; bool checkDelayedTasks = false; bool checkRunningTasks = false; lock ( LockObject ) { LOG("Remove('" + entry + ") - Lock acquired"); CheckValidity(); launchChecksAtEnd = Disposed ? false : true; entry.GetStatus((status) => { var id = entry.ID; switch (status) { case TaskEntry.Statuses.Removed: // Already removed // ASSERT( !AllTasks.ContainsKey(id), "The task is declared as Removed but is still in AllTasks" ); <= This can happen when 2 threads are removing the same TaskEntry at the same time => log but don't assert LOG("Remove('" + entry + ") - Is already removed"); return; case TaskEntry.Statuses.Delayed: { // Remove item from 'DelayedTasks' LOG("Remove('" + entry + ") - Is delayed"); var executionDate = entry.ExecutionDate; var list = DelayedTasks[executionDate]; var rc = list.Remove(id); ASSERT(rc, "Task was not in 'DelayedTasks'"); if (list.Count == 0) { // No more task for this DateTime LOG("Remove('" + entry + ") - No more task for " + executionDate); DelayedTasks.Remove(executionDate); } // The list has changed checkDelayedTasks = true; break; } case TaskEntry.Statuses.Queued: { LOG("Remove('" + entry + ") - Is Queued"); // Recreate 'QueuedTasks' without this task's ID QueuedTasks = new Queue <Guid>(QueuedTasks.Where((itemId) => (itemId != id))); // The list has changed checkRunningTasks = true; break; } case TaskEntry.Statuses.Running: { LOG("Remove('" + entry + ") - Is Running"); var rc = RunningTasks.Remove(id); ASSERT(rc, "Task was not in 'RunningTasks'"); checkRunningTasks = true; break; } default: throw new NotImplementedException("Unknown task status '" + status + "'"); } { // Remove the task from 'AllTasks' and set its status to 'Removed' LOG("Remove('" + entry + ") - Removing from AllTasks"); var rc = AllTasks.Remove(id); ASSERT(rc, "Task was not in 'AllTasks'"); entry.SetStatus(TaskEntry.Statuses.Removed); } }); CheckValidity(); } LOG("Remove('" + entry + ") - Lock released"); if (launchChecksAtEnd) { if (checkDelayedTasks) { // The 'DelayedTasks' has changed CheckDelayedTasks(); } if (checkRunningTasks) { // The 'RunningTasks' has changed CheckRunningTasks(); } LOG("Remove('" + entry + ") - Invoking " + onEntryRemoved.Count + " callbacks for 'OnEntryRemoved' event"); onEntryRemoved.Invoke(entry); } LOG("Remove('" + entry + ") - Exit"); }