在.Net中,ConcurrentQueue和BlockingCollection之间有什么区别?
Net中的在.Net中,ConcurrentQueue和BlockingCollection之间有什么区别?,.net,generics,c#-4.0,.net,Generics,C# 4.0,Net中的ConcurrentQueue和BlockingCollection之间有什么区别 为什么BlockingCollection可以通过ConcurrentQueue完成时最适合生产者-消费者操作?我必须改进以下代码中的任何内容吗 MessageSlotMachineGameStartOrAndStatusUpdate msg; while (!aCancellationToken.IsCancellationRequested) { try { thi
ConcurrentQueue
和BlockingCollection
之间有什么区别
为什么BlockingCollection
可以通过ConcurrentQueue
完成时最适合生产者-消费者操作?我必须改进以下代码中的任何内容吗
MessageSlotMachineGameStartOrAndStatusUpdate msg;
while (!aCancellationToken.IsCancellationRequested)
{
try
{
this.isStillConsumingMsg = true;
Boolean takeResult = this.msgQueue.TryTake(out msg, this.msgConsumeTimeOut, aCancellationToken);
if (takeResult)
{
if (msg != null)
{
this.ProcessMessage(msg);
}
}
else
{
break;
}
}
catch (OperationCanceledException err)
{
EngineManager.AddExceptionLog(err, "Signal Operation Canceled");
}
catch (Exception err)
{
EngineManager.AddExceptionLog(err, "Signal exception");
}
finally
{
this.isStillConsumingMsg = false;
}
}
BlockingCollection
有一个Take
方法,如果没有什么东西可以拿,它会阻止消费者,并等待生产方提供商品ConcurrentQueue
缺少这种方法-如果它是空的,消费者需要处理等待,生产者需要提供非空通知。BlockingCollection是并发集合的包装器,默认包装的集合是ConcurrentQueue;-)
发件人:
创建BlockingCollection对象时,可以指定“不”
不仅是有限容量,而且是要使用的集合类型。对于
例如,您可以为first-in指定一个ConcurrentQueue对象,
先出(FIFO)行为,或后进的ConcurrentStack对象,
先出(后进先出)行为。您可以使用任何
实现IProducerConsumerCollection接口。
BlockingCollection的默认集合类型是ConcurrentQueue。
BlockingCollection有一个Take()阻塞方法(因此得名),但它也有一个非常有趣的GetConsumingEnumerable()方法,该方法允许您无限循环:只有在集合中添加了某些内容时,代码才会进入代码内部的循环。 请参阅关于线程的优秀在线电子书 以下是此网站的代码示例:
public class PCQueue : IDisposable
{
BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public PCQueue (int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
Task.Factory.StartNew (Consume);
}
public void Dispose() { _taskQ.CompleteAdding(); }
public void EnqueueTask (Action action) { _taskQ.Add (action); }
void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
foreach (Action action in _taskQ.GetConsumingEnumerable())
action(); // Perform task.
}
}
公共类PCQueue:IDisposable
{
BlockingCollection_taskQ=新BlockingCollection();
公共PCQueue(int workerCount)
{
//为每个使用者创建并启动单独的任务:
对于(int i=0;i
@WAPGuy您可以使用。跟随链接并向下滚动查看如何使用它的示例。好的,当它向WaitHandle发出信号时?当它为空时或在Take method上给定的超时之后?@WAPGuy立即发出信号。timeout timespan用于确保如果在给定的超时内没有信号,该方法不会永远挂起?两者都是FiFO?@JohnDemetriou默认情况下,BlockingCollection
包装一个ConcurrentQueue
,因此答案是“是”。但是,您可以构造包含其他集合的BlockingCollection
对象来更改“take”的顺序。BlockingCollection使用CurrentQueue作为基础类型来保存数据。另外,它还具有阻塞功能。请注意,默认情况下,BlockingCollection使用ConcurrentQueue,但您可以在实现IProducerConsumerCollection的构造函数中指定另一种集合类型……例如,如果您希望LIFO,可以改为指定ConcurrentStack