В моем текущем приложении C # / NET 3.5 у меня есть очередь задач (поточно-ориентированная), и у меня есть 5 рабочих потоков, которые должны постоянно искать задачи в очереди. Если задача доступна, любой работник откажется от нее и предпримет необходимые действия.
Мой класс рабочих потоков выглядит следующим образом:
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;
}
}
Проблема в том, что когда очередь пуста, она потребляет слишком много ресурсов ЦП (почти 98%). Я попытался AutoResetEvent, чтобы уведомить работников, что очередь была изменена. Таким образом, они эффективно ждут, чтобы установить этот сигнал. Он снизил нагрузку на процессор почти до 0%, но я не совсем уверен, является ли это лучшим методом. Можете ли вы предложить лучший способ, чтобы потоки простаивали без ущерба для загрузки процессора?