c#中的队列是如何工作的? (允许的类型、初始化和字段)

Queue in c# how does it work? (types allowed, initialization and fields)

我正在用 C# 编写一个软件,但我无法理解队列。这是简化的情况:我已经有一个服务器和一个通信接口。服务器以一定的速率连续喷出数据,我想将其放入队列类型的缓冲区(数据进出的顺序非常重要,因为它将被解码,然后通过不同的方式发送到数据库联系)。问题是:当我尝试创建一个 class 来保存我的缓冲区(以及其他数据)时,我将其定义为

public class BufferingClass
{    
    public Queue<string[]> ServerDataBuffer;

    // rest of the code
}

但我收到错误 Queue does not exist in current context

我可以定义为

public class BufferingClass
{
    public Queue ServerDataBuffor

    // rest of the code
}

令人惊讶的是,将不同类型的对象分配到像这样定义的队列(如 INT STRING BOOL 或其他 classes 的数组)是可以的编译器方面(我胆子不够运行这样的程序)

所以这是我的问题。队列到底是什么?我不是在问一些琐碎的事情,比如它是一个 FIFO 集合。我只是感到惊讶,它不像该语言中的其他所有内容那样强类型化,即使它看起来像一个列表并且闻起来像一个列表,但以类似的方式定义它会引发编译器的危险信号。

另外Producer-Consumer问题是如何处理的?我知道,从生产者的角度来看,如果我继续将数据泵入我的 Queue,那么 OS 只会将其容量加倍,直到 运行 内存不足,甚至更多 space不能分配。但是,当缓冲区为空时调用 dequeue 时,会向代码发送什么信号?还是我必须处理 manually?特别是当一个线程正在添加到队列而另一个线程正在使用它时。

Public Queue<string[]> ServerDataBuffer;

这不是有效的 C# 行,这必须是 public,而不是 Public

我认为这是一个简单的错字。而且,正如@JonSkeet 提到的,有两个不同的 类、one of them is a generic, and second is not. Moreover, there is a ConcurrentQueue,它们面向多线程环境并且也是通用的。内部算法非常复杂,此处不再尝试解释。您可以找到它们的来源。

并发队列示例 (from MSDN):

// Construct a ConcurrentQueue.
ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

// Populate the queue. 
for (int i = 0; i < 10000; i++) cq.Enqueue(i);

// Peek at the first element. 
int result;
if (!cq.TryPeek(out result))
{
   Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
}
else if (result != 0)
{
   Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
}

int outerSum = 0;
// An action to consume the ConcurrentQueue.
Action action = () =>
{                
   int localSum = 0;
   int localValue;
   while (cq.TryDequeue(out localValue)) localSum += localValue;
   Interlocked.Add(ref outerSum, localSum);
};

// Start 4 concurrent consuming actions.
Parallel.Invoke(action, action, action, action);
Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);

并发 FIFO 队列的另一种实现是 BufferBlock class from TPL Dataflow library
如果您对 Producer/Consumer 大小有限的实现感兴趣,请参阅 BlockingCollection class implementing IProducerConsumerCollection<T>

如您所见,有很多针对您的问题的通用解决方案。阅读选项并根据需要选择它们。