1

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.

3
  • 1
    Why you take from synchQ but checks q? Where you modify q and what is it? Commented Oct 25, 2010 at 4:48
  • @Nick: public AsyncProcessor() { q = new Queue(); synchQ = Queue.Synchronized(q); } Commented Oct 25, 2010 at 4:50
  • @SPENDER: private ManualResetEvent PauseTrigger = new ManualResetEvent(false); Commented Oct 25, 2010 at 4:50

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Hightechrider, thanks but i am using .net 3.5. Please let me know if there is any alternative that I can use. I need a nicer and cleaner way of doing this.
Take a look at the second answer here: stackoverflow.com/questions/1116249/…
@Sumee, you can use new thread-safe collection from .NET 4 in 3.5, just download Reactive Extensions for .NET (Rx) bit.ly/dnHhes and reference System.Threading.dll from it (you don't need others). So you can go with nice ConcurrentQueue.
@Nick, i'll then have to ship System.Threading.dll with my solution and I am not sure whether i can legally redistribute it or not.
2

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

1 Comment

Thanks, that's a better solution.
1

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 Comments

I don't think so. Even if it takes longer than 100ms, it shouldn't matter because it is a synchronous call. or m i wrong?
If it's synchronous, I agree. It's a bit of a guessing game. Profiler?
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.