public void DoWork() { try { while (mKeepAlive) { mSignal.WaitOne(); mActiveWorkItem.DoWork(); var finishedWorkItem = mActiveWorkItem; mActiveWorkItem = null; // Signal the thread pool that this work is complete. We will then // call the work item's callback method to signal the original caller. mOnFinishedCallback(this, finishedWorkItem); // Wait for next work mSignal.Reset(); mIsWorking = false; } } catch (ThreadAbortException t) { Debug.LogWarning("A worker thread has been aborted in the thread pool: " + t.Message); } finally { mActiveWorkItem = null; mSignal.Close(); } }
// Called from single-threaded context public void AssignWork(ThreadedWork workToDo) { Precondition.IsNotNull(workToDo); if (!mIsWorking) { mIsWorking = true; mActiveWorkItem = workToDo; // Start work processing mSignal.Set(); } }
/// <summary> /// Enqueues work to be done. Note that this must be called from the main thread, /// it is not thread-safe. The pool only supports a maximum number of work that can /// be done concurrently as well as work that is pending. If both pipelines are at /// capacity then the function will return false and the work won't be enqueued. /// </summary> /// <returns>True if the work was enqueued.</returns> public bool EnqueueWork(ThreadedWork workRequest) { if (mPendingTasks.Count < mMaxQueueSize) { mPendingTasks.Enqueue(workRequest); // Signal that there's work afoot. This may or may not dequeue the // next item however. In either case, we return true since we could // only have hoped to enqueue it. TryToPickupNextWork(); return(true); } return(false); }
private void WorkerFinishedHandler(Worker worker, ThreadedWork finishedWorkItem) { // TODO: This might be a bug. // Investigate if we need to marshal this back onto the main thread if it's not already // on the main thread. Otherwise we break the restriction that we cannot enqueue new work from // off-thread // Signal the original caller that the requested work is complete. We guarantee // that the just-finished worker instance is immediately ready for the next task // once you've reached this callback. if (mEnableWorkerCallbacks) { finishedWorkItem.FinishedWorkCallback(); } // Now that a worker has been freed up, we can tell the thread pool to try // and pick up the next task. if (mEnableDoWorkImmediatelyOnCompletion) { TryToPickupNextWork(); } }