使用异步队列处理,CPU使用率几乎达到100%

时间:2010-10-25 04:43:42

标签: c# .net

我有一个异步队列处理器,它有一个Run方法,可以暂停100ms运行。此代码导致CPU使用率几乎达到100%。遵循此异步队列处理器的“运行”方法的thr代码。

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

如果我做错了,请告诉我。

4 个答案:

答案 0 :(得分:3)

如果队列为空并且设置了PauseTrigger,则它将旋转并使用100%CPU。

如果您使用的是.NET 4,那么BlockingCollection提供了一种更好的方法来处理排队和出队。

答案 1 :(得分:2)

一个简单的解决方法是尝试Thread.Sleep (100);而不是PauseTrigger.WaitOne(100)

如果您调用哪个线程OnHeartBeat无关紧要,可以使用此类。

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());
            }
        }
    }
然后你可以使用

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

q.Push (new ServiceMessage (someArgs));

答案 2 :(得分:1)

OnHeartBeat(msg.Args)完成时间超过100毫秒?

为什么不在分析器中运行代码以找出CPU周期的用途?

请参阅此问题:Any Good Free .NET Profiler?

答案 3 :(得分:0)

2件事......为什么你在检查q.count时会出现同步问题?

尝试放置一个计数器,看看你是否因为synchQ和q.count检查而遇到无限循环