public void Init() { PriorityQueue pq = new PriorityQueue(); Assert.AreEqual(0, pq.Count); Assert.IsNull(pq.Dequeue()); Assert.AreEqual(0, pq.Count); }
public void MultipleWorkItemsMultiplePriorities() { // Get all the available priorities WorkItemPriority [] priorities = Enum.GetValues(typeof(WorkItemPriority)) as WorkItemPriority []; // Create an array of priority items PriorityItem [] priorityItems = new PriorityItem[priorities.Length]; // Create a priority item for each priority int i = priorities.Length; foreach(WorkItemPriority workItemPriority in priorities) { --i; priorityItems[i] = new PriorityItem(workItemPriority); } // Create a PermutationGenerator for the priority items PermutationGenerator permutations = new PermutationGenerator(priorityItems); int count = 0; // Iterate over the permutations foreach(object [] permutation in permutations) { ++count; Console.Write("Permutation #" + count + " : "); for(int j = 0; j < permutation.Length; ++j) { PriorityItem pi = permutation[j] as PriorityItem; Console.Write(pi.WorkItemPriority + ", "); } Console.WriteLine(); // Create a priority queue PriorityQueue pq = new PriorityQueue(); // Enqueue each priority item according to the permutation for(i = 0; i < permutation.Length; ++i) { PriorityItem priorityItem = permutation[i] as PriorityItem; pq.Enqueue(priorityItem); } // Make sure all the priority items are in the queue Assert.AreEqual(priorityItems.Length, pq.Count); // Compare the order of the priority items for(i = 0; i < priorityItems.Length; ++i) { PriorityItem priorityItem = pq.Dequeue() as PriorityItem; Assert.AreSame(priorityItems[i], priorityItem); } } }
public void MultipleWorkItemsOnePriority() { WorkItemPriority [] priorities = Enum.GetValues(typeof(WorkItemPriority)) as WorkItemPriority []; foreach(WorkItemPriority wip in priorities) { PriorityQueue pq = new PriorityQueue(); PriorityItem [] priorityItems = new PriorityItem[10]; for(int i = 0; i < priorityItems.Length; ++i) { priorityItems[i] = new PriorityItem(wip); pq.Enqueue(priorityItems[i]); Assert.AreEqual(i+1, pq.Count, "Failed for priority {0} item count {1}", wip, i+1); } for(int i = 0; i < priorityItems.Length; ++i) { PriorityItem pi = pq.Dequeue() as PriorityItem; Assert.AreEqual(priorityItems.Length-(i+1), pq.Count, "Failed for priority {0} item count {1}", wip, i+1); Assert.IsNotNull(pi, "Failed for priority {0} item count {1}", wip, i+1); Assert.AreSame(pi, priorityItems[i], "Failed for priority {0} item count {1}", wip, i+1); } Assert.AreEqual(0, pq.Count, "Failed for priority {0}", wip); Assert.IsNull(pq.Dequeue()); Assert.AreEqual(0, pq.Count); } }
public void OneWorkItem() { WorkItemPriority [] priorities = Enum.GetValues(typeof(WorkItemPriority)) as WorkItemPriority []; foreach(WorkItemPriority wip in priorities) { PriorityQueue pq = new PriorityQueue(); PriorityItem pi = new PriorityItem(wip); pq.Enqueue(pi); Assert.AreEqual(1, pq.Count, "Failed for priority {0}", wip); PriorityItem pi2 = pq.Dequeue() as PriorityItem; Assert.IsNotNull(pi2, "Failed for priority {0}", wip); Assert.AreSame(pi, pi2, "Failed for priority {0}", wip); Assert.AreEqual(0, pq.Count, "Failed for priority {0}", wip); } }
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue) { lock (_lock) { // Got here from OnWorkItemCompletedCallback() if (decrementWorkItemsInStpQueue) { --_workItemsInStpQueue; if (_workItemsInStpQueue < 0) { _workItemsInStpQueue = 0; } --_workItemsExecutingInStp; if (_workItemsExecutingInStp < 0) { _workItemsExecutingInStp = 0; } } // If the work item is not null then enqueue it if (null != workItem) { workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup; RegisterToWorkItemCompletion(workItem.GetWorkItemResult()); _workItemsQueue.Enqueue(workItem); //_stp.IncrementWorkItemsCount(); if ((1 == _workItemsQueue.Count) && (0 == _workItemsInStpQueue)) { _stp.RegisterWorkItemsGroup(this); IsIdle = false; _isIdleWaitHandle.Reset(); } } // If the work items queue of the group is empty than quit if (0 == _workItemsQueue.Count) { if (0 == _workItemsInStpQueue) { _stp.UnregisterWorkItemsGroup(this); IsIdle = true; _isIdleWaitHandle.Set(); if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0) { _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle)); } } return; } if (!_isSuspended) { if (_workItemsInStpQueue < _concurrency) { WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem; try { _stp.Enqueue(nextWorkItem); } catch (ObjectDisposedException e) { e.GetHashCode(); // The STP has been shutdown } ++_workItemsInStpQueue; } } } }
/// <summary> /// Waits for a work item or exits on timeout or cancel /// </summary> /// <param name="millisecondsTimeout">Timeout in milliseconds</param> /// <param name="cancelEvent">Cancel wait handle</param> /// <returns>Returns true if the resource was granted</returns> public WorkItem DequeueWorkItem( int millisecondsTimeout, WaitHandle cancelEvent) { /// This method cause the caller to wait for a work item. /// If there is at least one waiting work item then the /// method returns immidiately with true. /// /// If there are no waiting work items then the caller /// is queued between other waiters for a work item to arrive. /// /// If a work item didn't come within millisecondsTimeout or /// the user canceled the wait by signaling the cancelEvent /// then the method returns false to indicate that the caller /// didn't get a work item. WaiterEntry waiterEntry = null; WorkItem workItem = null; lock (this) { ValidateNotDisposed(); // If there are waiting work items then take one and return. if (_workItems.Count > 0) { workItem = _workItems.Dequeue() as WorkItem; return(workItem); } // No waiting work items ... else { // Get the wait entry for the waiters queue waiterEntry = GetThreadWaiterEntry(); // Put the waiter with the other waiters PushWaiter(waiterEntry); } } // Prepare array of wait handle for the WaitHandle.WaitAny() var waitHandles = new[] { waiterEntry.WaitHandle, cancelEvent }; // Wait for an available resource, cancel event, or timeout. // During the wait we are supposes to exit the synchronization // domain. (Placing true as the third argument of the WaitAny()) // It just doesn't work, I don't know why, so I have lock(this) // statments insted of one. int index = WaitHandle.WaitAny( waitHandles, millisecondsTimeout, true); lock (this) { // success is true if it got a work item. bool success = (0 == index); // The timeout variable is used only for readability. // (We treat cancel as timeout) bool timeout = !success; // On timeout update the waiterEntry that it is timed out if (timeout) { // The Timeout() fails if the waiter has already been signaled timeout = waiterEntry.Timeout(); // On timeout remove the waiter from the queue. // Note that the complexity is O(1). if (timeout) { RemoveWaiter(waiterEntry, false); } // Again readability success = !timeout; } // On success return the work item if (success) { workItem = waiterEntry.WorkItem; if (null == workItem) { workItem = _workItems.Dequeue() as WorkItem; } } } // On failure return null. return(workItem); }
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue) { lock (_lock) { // Got here from OnWorkItemCompletedCallback() if (decrementWorkItemsInStpQueue) { --_workItemsInStpQueue; if (_workItemsInStpQueue < 0) { _workItemsInStpQueue = 0; } --_workItemsExecutingInStp; if (_workItemsExecutingInStp < 0) { _workItemsExecutingInStp = 0; } } // If the work item is not null then enqueue it if (null != workItem) { workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup; RegisterToWorkItemCompletion(workItem.GetWorkItemResult()); _workItemsQueue.Enqueue(workItem); //_stp.IncrementWorkItemsCount(); if ((1 == _workItemsQueue.Count) && (0 == _workItemsInStpQueue)) { _stp.RegisterWorkItemsGroup(this); Trace.WriteLine("WorkItemsGroup " + Name + " is NOT idle"); _isIdleWaitHandle.Reset(); } } // If the work items queue of the group is empty than quit if (0 == _workItemsQueue.Count) { if (0 == _workItemsInStpQueue) { _stp.UnregisterWorkItemsGroup(this); Trace.WriteLine("WorkItemsGroup " + Name + " is idle"); _isIdleWaitHandle.Set(); _stp.QueueWorkItem(this.FireOnIdle); } return; } if (!_workItemsGroupStartInfo.StartSuspended) { if (_workItemsInStpQueue < _concurrency) { WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem; _stp.Enqueue(nextWorkItem, true); ++_workItemsInStpQueue; } } } }