Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.Net中,ConcurrentQueue和BlockingCollection之间有什么区别?_.net_Generics_C# 4.0 - Fatal编程技术网

在.Net中,ConcurrentQueue和BlockingCollection之间有什么区别?

在.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

Net中的
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