Sumee Sumee - 1 month ago 20
C# Question

CPU usage goes to almost 100% with Async queue processing

I have an async queue processor that has a Run method which keeps running with a pause of 100ms. This code results in CPU usage of almost 100%. following the thr code of 'Run' method of this async queue processor.

private void Run()
{
while (true)
{
if (q.Count != 0)
{
ServiceMessage msg = (ServiceMessage)synchQ.Dequeue();
OnHeartBeat(msg.Args);
}
PauseTrigger.WaitOne(100, false);
}
}


Please let me know if there is something wrong that I am doing.

Answer

A simple fix would be to try Thread.Sleep (100); rather than PauseTrigger.WaitOne(100)

If it doesn't matter for you which thread OnHeartBeat is called on you can use this class.

public class ProcessingQueue<T>
{


    private readonly object _lock = new object();
    private readonly Queue<T> _queue = new Queue<T>();
    private readonly Action<T> _workMethod;
    private bool _pumpIsAlive;  

    private void Pump()
    {
        while (true)
        {

            lock (this._lock)
            {
                item = this._queue.Dequeue();
            }

            this._workMethod(item);

            lock (this._lock)
            {
                if (this._queue.Count == 0)
                {
                    this._pumpIsAlive = false;
                    break;
                }
            }
        }

    /// <summary>
    /// Pushes an item onto the processing the queue to be handled at an indeterminate time.
    /// </summary>
    /// <param name="item">The item to push onto the queue.</param>
    public void Push(T item)
    {
        lock (this._lock)
        {
            this._queue.Enqueue(new Containter(item));
            this.StartPump();
        }
    }

    private void StartPump()
    {
        lock (this._lock)
        {
            if (!this._pumpIsAlive)
            {
                this._pumpIsAlive= true;
                ThreadPool.QueueUserWorkItem(o => this.Pump());
            }
        }
    }

which you could then use like:

var q = new ProcessingQueue<ServiceMessage> ( sm => OnHeartBeat(sm.args));

q.Push (new ServiceMessage (someArgs));