What is the most efficient CPU method to get workflows waiting for tasks?

In my current C # / NET 3.5 application, I have a task queue (thread safe) and I have 5 workflows that should constantly look for tasks in the queue. If the task is available, any one employee will deactivate the task and take the necessary actions.

My work flow class is as follows:

public class WorkerThread
{
    //ConcurrentQueue is my implementation of thread safe queue
    //Essentially just a wrapper around Queue<T> with synchronization locks
    readonly ConcurrentQueue<CheckPrimeTask> mQ; 
    readonly Thread mWorker;
    bool mStop;

    public WorkerThread (ConcurrentQueue<CheckPrimeTask> aQ) {
        mQ = aQ;
        mWorker = new Thread (Work) {IsBackground = true};
        mStop = false;
    }

    private void Work () {
        while (!mStop) {
            if (mQ.Count == 0) {
                Thread.Sleep (0);
                continue;
            }

            var task = mQ.Dequeue ();
            //Someone else might have been lucky in stealing
            //the task by the time we dequeued it!!
            if (task == null) 
                continue;

            task.IsPrime = IsPrime (task.Number);
            task.ExecutedBy = Thread.CurrentThread.ManagedThreadId;
            //Ask the threadpool to execute the task callback to 
            //notify completion
            ThreadPool.QueueUserWorkItem (task.CallBack, task);
        }
    }

    private bool IsPrime (int number) {
        int limit = Convert.ToInt32 (Math.Sqrt (number));
        for (int i = 2; i <= limit; i++) {
            if (number % i == 0)
                return false;
        }

        return true;
    }

    public void Start () {
        mStop = false;
        mWorker.Start ();
    }

    public void Stop () {
        mStop = true;
    }
}

, , CPU ( 98%). AutoResetEvent, , . , . 0%, , . , ?

+5
4

BlockingQueue. , Monitor.Wait(), . , Monitor.Pulse(), , .

- semaphore. , , Release(). , WaitOne().

+7

Thread.Sleep(0) , . - , 0, . 10, ...

+2

, .

- . 0 .

Another way is to use reset (automatic or manual), as suggested by Mitch Wheat in the comments.

You can also create some kind of IdleTask that has a sleeping thread for a certain time, and if your queue is empty, just handle the IdleTask (which will translate the thread).

0
source

If your queue is thread safe, you won’t need to do this ...

    //Someone else might have been lucky in stealing 
    //the task by the time we dequeued it!! 
    if (task == null)  
        continue; 
0
source

All Articles