/// <summary> /// Used by the worker thread to process items. /// </summary> private void Run() { while (!Stopping) { lock (lockObject) { // Wait until we have pending work items if (IsWorkQueueEmpty()) { Monitor.Wait(lockObject); } } // Loop until we exhaust the queue bool queueFull = true; while (queueFull && !Stopping) { // Get an item from the queue AsyncOperation asyncOp = null; object request = null; int priority = 0; lock (lockObject) { // Check queues Tuple <AsyncOperation, int> work = GetWork(); asyncOp = work.Item1; priority = work.Item2; if (asyncOp != null) { request = asyncOp.UserSuppliedState; } // Check if the item was removed if (request != null && cancelledItems.ContainsKey(request)) { request = null; } } if (request != null) { Exception error = null; // Start the work QueuedWorkerDoWorkEventArgs arg = new QueuedWorkerDoWorkEventArgs(request, priority); try { // Raise the do work event OnDoWork(arg); } catch (Exception e) { error = e; } // Raise the work complete event QueuedWorkerCompletedEventArgs arg2 = new QueuedWorkerCompletedEventArgs(request, arg.Result, priority, error, arg.Cancel); if (!Stopping) { asyncOp.PostOperationCompleted(workCompletedCallback, arg2); } } else if (asyncOp != null) { asyncOp.OperationCompleted(); } // Check if the cache is exhausted lock (lockObject) { queueFull = !IsWorkQueueEmpty(); } } } }