public void BinarySearchIncomparable() { RandomAccessQueue <object> queue = new RandomAccessQueue <object>(); try { // object doesn't implement IComparable queue.BinarySearch(new object()); Assert.Fail("Expected exception"); } catch (ArgumentException) { // Expected } }
/// <summary> /// Adds a work item to the queue and potentially start a new thread. /// A thread is started if there are no idle threads or if there is already /// something on the queue - but in each case, only if the total number of /// threads is less than the maximum. /// </summary> /// <param name="workItem">The actual work item to add to the queue.</param> public void AddWorkItem([NotNull] ThreadPoolWorkItem workItem) { if (workItem == null) { throw new ArgumentNullException(nameof(workItem)); } bool startNewThread; lock (_stateLock) { lock (_queueLock) { if (_queue.Count == 0) { _queue.Enqueue(workItem); } else { // Work out where in the queue the item should go // Common case: it belongs at the end if (_queue[_queue.Count - 1].Priority >= workItem.Priority) { _queue.Enqueue(workItem); } else { // This will find the complement of the correct position, due to the // "interesting" nature of PriorityComparer. int position = _queue.BinarySearch(workItem, PriorityComparer.Instance); _queue.Enqueue(workItem, ~position); } } startNewThread = WorkingThreads + _queue.Count > TotalThreads && TotalThreads < MaxThreads; // Always pulse the queueLock, whether there's something waiting or not. // This is easier than trying to work out for sure whether or not it's // worth pulsing, and errs on the side of caution. Monitor.Pulse(_queueLock); } } if (startNewThread) { StartWorkerThread(); } }
public void BinarySearchIncomparable() { RandomAccessQueue<object> queue = new RandomAccessQueue<object>(); try { // object doesn't implement IComparable queue.BinarySearch(new object()); Assert.Fail("Expected exception"); } catch (ArgumentException) { // Expected } }