当前位置: 首页 > 编程语言 > C#

没有Thread.Sleep共享的并发集合吃太多的cpu

时间:2023-04-10 10:54:43 C#

没有Thread.Sleep的并发集合吃太多的cpuBlockingCollection或ConcurrentQueue的正确用法是什么,这样你就可以自由地出列项目而不会烧掉一半或更多CPU使用线程?我使用2个线程运行一些测试,除非我有至少50~100毫秒的Thread.Sleep,否则它总是至少占用我CPU的50%。这是一个人为的例子:privatevoid_DequeueItem(){objecto=null;while(socket.Connected){while(!listOfQueueItems.IsEmpty){if(listOfQueueItems.TryDequeue(outo)){//使用数据}}}}对于上面的例子,我必须设置一个thread.sleep所以cpu不会爆炸。注意:我也尝试过不计时IsEmpty检查,结果相同。不是因为BlockingCollection或ConcurrentQueue,而是while循环:while(socket.Connected){while(!listOfQueueItems.IsEmpty){/*code*/}}当然是占用cpu;因为如果队列为空,则while循环Like:while(true);反过来又会占用cpu资源。这不是使用ConcurrentQueue的好方法,您应该使用AutoResetEvent,这样每当添加项目时您都会收到通知。示例:privateConcurrentQueue_queue=newConcurrentQueue();私有AutoResetEvent_queueNotifier=newAutoResetEvent(false);//在生产者处:_queue.Enqueue(newData());_queueNotifier.Set();//在消费者处:while(true)//或某些条件{_queueNotifier.WaitOne();//这里我们将阻塞直到收到信号通知。数据数据;if(_queue.TryDequeue(outdata)){//handlethedata}}为了更好地使用BlockingCollection,您应该使用GetConsumingEnumerable()来等待添加项目,例如://声明缓冲区privateBlockingCollection_buffer=newBlockingCollection(新并发队列());//在生产者方法:_messageBuffer.Add(newData());//在消费者foreach(_buffer.GetConsumingEnumerable()中的数据数据)//它会自动阻塞在这里等待添加新项目并且它不会占用cpu{//处理这里的数据。在这种情况下,您确实想要使用BlockingCollection类。它被设计为阻塞,直到一个项目出现在队列中。这种性质的集合通常称为阻塞队列。这个特定的实现对于多个生产者和多个消费者来说是安全的,如果您尝试自己实现它,这将是非常困难的。如果您使用BlockingCollection那么这就是您的代码的样子。privatevoid_DequeueItem(){while(socket.Connected){objecto=listOfQueueItems.Take();//使用数据}}如果队列为空,Take方法将自动阻塞。它以一种将线程置于SleepWaitJoin状态的方式进行阻塞,这样它就不会消耗CPU资源。BlockingCollection在于它还使用了低锁策略来提高性能。这意味着Take会检查队列中是否有项,如果没有,那么它会临时执行自旋等待以防止线程的上下文切换。如果队列仍然是空的,那么它将线程置于休眠状态。这意味着BlockingCollection在并发执行方面将具有ConcurrentQueue提供的一些性能优势。Thread.Sleep()只能在队列为空时调用:privatevoidDequeueItem(){objecto=null;while(socket.Connected){如果(listOfQueueItems.IsEmpty){Thread.Sleep(50);}elseif(listOfQueueItems.TryDequeue(outo)){//使用数据}}}否则你应该考虑使用事件。以上就是C#学习教程的全部内容:ConcurrentcollectioneatsmuchcpuwithoutThread.Sleep。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处: