c# 高级编程 10章210页 【集合】【队列Queue<T>】

121 阅读2分钟

Queue<T>

  • 在内部,使用一个数组,元素类型为T
  • 实现了IEnumerable<T>接口
  • 实现了ICollection接口
  • 没有实现ICollection<T>接口,所以Add()Remove()不能用
  • 没有实现IList<T>接口,所以不能用索引器访问队列

Queue<T> 成员

成员说明
Count元素个数
Enqueue()在队列一端添加一个元素
Dequeue() 在队列头部,读取和删除一个元素。如果队列中没有元素,则抛出InvalidOperationException
Peek()在队列头部,读取一个元素,但不删除
TrimExcess() 从队列头部去除空元素,重置队列容量

Queue<T>的容量

  • 默认的构造函数,创建一个空队列
  • 默认构造函数没有定义容量,容量就会递增, 4, 8, 16, 32
  • 构造函数的重载,可以传递一个IEnumerable<T>到队列里

示例

    class Program
    {
        static async Task Main()
        {
            var dm = new DocumentManager();

            Task processDocuments = ProcessDocuments.StartAsync(dm);

            // Create documents and add them to the DocumentManager
            for (int i = 0; i < 30; i++)
            {
                var doc = new Document($"Doc {i}", "content");
                dm.AddDocument(doc);
                Console.WriteLine($"Added document {doc.Title}");
                await Task.Delay(new Random().Next(20));
            }
            await processDocuments;

            Console.ReadLine();
        }
    }
    public class Document
    {
        public Document(string title, string content)
        {
            Title = title;
            Content = content;
        }

        public string Title { get; }
        public string Content { get; }
    }
    public class DocumentManager
    {
        private readonly object _syncQueue = new object();

        private readonly Queue<Document> _documentQueue = new Queue<Document>();

        public void AddDocument(Document doc)
        {
            lock (_syncQueue)
            {
                _documentQueue.Enqueue(doc);
            }
        }

        public Document GetDocument()
        {
            Document doc = null;
            lock (_syncQueue)
            {
                doc = _documentQueue.Dequeue();
            }
            return doc;
        }

        public bool IsDocumentAvailable => _documentQueue.Count > 0;
    }
    public class ProcessDocuments
    {
        public static Task StartAsync(DocumentManager dm) =>
            Task.Run(new ProcessDocuments(dm).Run);

        protected ProcessDocuments(DocumentManager dm) =>
            _documentManager = dm ?? throw new ArgumentNullException(nameof(dm));

        private DocumentManager _documentManager;

        protected async Task Run()
        {
            while (true)
            {
                if (_documentManager.IsDocumentAvailable)
                {
                    Document doc = _documentManager.GetDocument();
                    Console.WriteLine($"Processing document {doc.Title}");
                }
                await Task.Delay(new Random().Next(20));
            }
        }
    }

输出:

Added document Doc 0
Processing document Doc 0
Added document Doc 1
Added document Doc 2
Processing document Doc 1
Processing document Doc 2
Added document Doc 3
Added document Doc 4
Processing document Doc 3
Processing document Doc 4
Added document Doc 5
Added document Doc 6
Processing document Doc 5
Processing document Doc 6
Added document Doc 7
Processing document Doc 7
Added document Doc 8
Processing document Doc 8
Added document Doc 9
Added document Doc 10
Added document Doc 11
Processing document Doc 9
Added document Doc 12
Processing document Doc 10
Processing document Doc 11
Added document Doc 13
Added document Doc 14
Processing document Doc 12
Added document Doc 15
Added document Doc 16
Processing document Doc 13
Processing document Doc 14
Added document Doc 17
Processing document Doc 15
Processing document Doc 16
Added document Doc 18
Processing document Doc 17
Added document Doc 19
Added document Doc 20
Processing document Doc 18
Processing document Doc 19
Added document Doc 21
Added document Doc 22
Added document Doc 23
Processing document Doc 20
Processing document Doc 21
Added document Doc 24
Processing document Doc 22
Added document Doc 25
Added document Doc 26
Processing document Doc 23
Processing document Doc 24
Added document Doc 27
Processing document Doc 25
Processing document Doc 26
Added document Doc 28
Added document Doc 29
Processing document Doc 27
Processing document Doc 28
Processing document Doc 29