开发者

CPU usage goes to almost 100% with Async queue processing

开发者 https://www.devze.com 2023-01-21 14:36 出处:网络
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%. followi开发者_JAVA技巧ng the thr code of \'Run\' method

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%. followi开发者_JAVA技巧ng 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.


If queue is empty and PauseTrigger is set this will spin and use 100% CPU.

If you are using .NET 4 then BlockingCollection provides a much nicer way to handle queueing and dequeing.


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));


OnHeartBeat(msg.Args) takes longer than 100ms to complete?

Why not run your code in a profiler to find out where the CPU cycles are being spent?

See this question: Any Good Free .NET Profiler?


2 things... why are you dequeueing synchQ while checking for q.count?

Try putting a counter and see if you are running into an infinite loop because of synchQ and q.count check

0

精彩评论

暂无评论...
验证码 换一张
取 消