C#中Queue是最轻量、最符合FIFO直觉的顺序处理容器,但不支持索引访问、非线程安全、空队列调用Dequeue()会抛异常;仅当需严格“先入先出、头取尾加”时才语义正确,如任务调度、打印排队、HTTP缓冲。
直接说结论:C# 中是最轻量、最符合 FIFO 直觉的顺序处理容器,但不是万能的——它不支持索引访问、不能安全用于多线程默认场景、空队列调用会崩。
什么时候该用
而不是
或数组
当你明确需要「严格按插入顺序逐个取走、且只从头取、只从尾加」时,
才是语义正确的选择。比如任务调度器轮询、打印请求排队、HTTP 请求缓冲。
支持随机访问和中间插入,但用它模拟队列容易写出
这种 O(n) 操作,性能差且意图模糊
数组固定长度,扩容需手动处理;而
内部用循环数组实现,
平均时间复杂度是 O(1),扩容自动完成
如果只是遍历一次、不修改结构,用
遍历
安全;但别试图用
——它没这个索引器
和
的关键区别与风险点
移除并返回队首元素;
只读取不移除。二者都要求队列非空,否则抛出
。
常见错误:在未检查
的情况下直接调用
,尤其在多线程或异步回调中极易触发异常
安全写法不是靠 try-catch,而是先判断:
适合“预检”场景,比如日志队列中先看下下一条是什么再决定是否丢弃
注意:
返回的是引用类型对象的引用,或值类型的副本;对引用类型成员的修改会反映在队列中原始对象上
初始化容量与性能影响
默认初始容量为 32,增长因子为 2.0。频繁扩容会影响吞吐,尤其在高吞吐生产者-消费者模型中。
C知道
CSDN推出的一款AI技术问答工具
下载
如果你能预估峰值大小(例如每秒入队 1000 条、处理延迟 ≤1s),建议显式指定容量:
传入
构造(如
)会一次性复制,内部容量 = 源集合长度,避免首次
就扩容
不要为了“省空间”设过小容量(如
),连续入队 5 次就会触发第一次扩容,反而增加拷贝开销
多线程场景下为什么不能直接用
本身不是线程安全的。多个线程同时
或
可能导致
错乱、数据丢失甚至
。
别用
包裹每次操作——虽然可行,但锁粒度太细,严重拖慢吞吐
正确替代是
,它提供无锁的
和
,失败时返回
而非抛异常
不提供
属性(因并发下统计无意义),改用
判断更可靠
如果必须用普通
做跨线程传递,请确保由单一生产者 + 单一消费者协作,且通过信号机制(如
)同步,而非共享访问
真正容易被忽略的点是:FIFO 不等于“顺序绝对可靠”。当业务逻辑依赖严格时间序或处理序时,得考虑
和
之间是否存在竞态、重试、丢弃等外部干扰——队列本身只保证内部操作顺序,不兜底业务语义。
QueueDequeue()QueueListQueueListlist.RemoveAt(0)QueueEnqueueforeachQueuequeue[i]Dequeue()Peek()Dequeue()Peek()InvalidOperationExceptionCount > 0Dequeue()if (queue.Count > 0) { var item = queue.Dequeue(); ... }Peek()Peek()Queuenew Queue(1024) IEnumerablenew Queue(array) Enqueuenew Queue(4) QueueQueueEnqueueDequeueCountNullReferenceExceptionlockConcurrentQueueTryEnqueueTryDequeuefalseConcurrentQueueCountIsEmptyQueueAutoResetEventEnqueueDequeue