我有一个异步队列处理器,它有一个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);
}
}
如果我做错了,请告诉我。
答案 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)
答案 3 :(得分:0)
2件事......为什么你在检查q.count时会出现同步问题?
尝试放置一个计数器,看看你是否因为synchQ和q.count检查而遇到无限循环