两者的正确用法是什么,BlockingCollection
or ConcurrentQueue
这样您就可以自由地将项目出列,而不会使用线程消耗一半或更多的 CPU 资源?
我使用 2 个线程运行一些测试,除非我的 Thread.Sleep 至少为 50~100 毫秒,否则它总是会占用至少 50% 的 CPU。
这是一个虚构的例子:
private void _DequeueItem()
{
object o = null;
while(socket.Connected)
{
while (!listOfQueueItems.IsEmpty)
{
if (listOfQueueItems.TryDequeue(out o))
{
// use the data
}
}
}
}
对于上面的例子,我必须设置一个thread.sleep,这样CPU就不会崩溃。
注意:我也尝试过没有进行 IsEmpty 检查,结果是相同的。
这并不是因为BlockingCollection
or ConcurrentQueue
,但是 while 循环:
while(socket.Connected)
{
while (!listOfQueueItems.IsEmpty)
{ /*code*/ }
}
当然会降低cpu的性能;因为如果队列为空,那么 while 循环就像:
while (true) ;
这反过来又会消耗CPU资源。
这不是一个好的使用方法ConcurrentQueue
你应该使用AutoResetEvent
有了它,每当添加项目时,您都会收到通知。
例子:
private ConcurrentQueue<Data> _queue = new ConcurrentQueue<Data>();
private AutoResetEvent _queueNotifier = new AutoResetEvent(false);
//at the producer:
_queue.Enqueue(new Data());
_queueNotifier.Set();
//at the consumer:
while (true)//or some condition
{
_queueNotifier.WaitOne();//here we will block until receive signal notification.
Data data;
if (_queue.TryDequeue(out data))
{
//handle the data
}
}
为了更好地使用BlockingCollection
你应该使用GetConsumingEnumerable()
等待添加项目,例如:
//declare the buffer
private BlockingCollection<Data> _buffer = new BlockingCollection<Data>(new ConcurrentQueue<Data>());
//at the producer method:
_messageBuffer.Add(new Data());
//at the consumer
foreach (Data data in _buffer.GetConsumingEnumerable())//it will block here automatically waiting from new items to be added and it will not take cpu down
{
//handle the data here.
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)