/// <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 (paused || IsWorkQueueEmpty()) { Monitor.Wait(lockObject); } } // Loop until we exhaust the queue bool queueFull = true; while (queueFull && !Stopping && !Paused) { // Get an item from the queue AsyncOperation asyncOp = null; object request = null; int priority = 0; lock (lockObject) { // Check queues Utility.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; object result = null; bool cancel = false; // Start the work try { // Raise the do work event QueuedWorkerDoWorkEventArgs doWorkArg = new QueuedWorkerDoWorkEventArgs(request, priority); OnDoWork(doWorkArg); result = doWorkArg.Result; cancel = doWorkArg.Cancel; } catch (Exception e) { error = e; } // Raise the work complete event QueuedWorkerCompletedEventArgs workCompletedArg = new QueuedWorkerCompletedEventArgs(request, result, priority, error, cancel); if (!Stopping) { asyncOp.PostOperationCompleted(workCompletedCallback, workCompletedArg); } } else if (asyncOp != null) { asyncOp.OperationCompleted(); } // Check if the cache is exhausted lock (lockObject) { queueFull = !IsWorkQueueEmpty(); } } } }