集合之队列

队列是其元素以先进先出的方式处理的集合。先放入队列的元素会先读取。

队列使用System.Collections.Generic 名称空间中的泛型类Queue<T>实现。在内部,Queue<T>类使用T类型的数组,这类似于List<T>类型。它实现ICollection和IEnumerable<T>接口,但没有实现ICollection<T>接口,因为这个接口定义的Add()和Remove()

方法不能用于队列。

Queue<T>类的方法如下:

count:返回队列中元素个数;

Enqueue:在队列一端添加一个元素;

Dequeue:在队列的头部读取和删除元素。如果在调用Dequeue()方法是,队列中不在有元素,就抛出一个InvalidOperationException类型的异常;

Peek:从队列的头部读取一个元素,但不删除它;

TrimExcess:重新设置队列的容量。Dequeue()方法从队列中删除元素,但它不会重新设置队列的容量。要从队列的头部去除空元素,应使用TrimExcess()方法。

实现队列的案例:

    /// <summary>
    /// 接口文档
    /// </summary>
    public interface IDocument
    {
        string Title { get; set; }
        string Content { get; set; }
    }
    /// <summary>
    /// 文档
    /// </summary>
    public class Document : IDocument
    {
        public Document() { }
        public Document(string title, string content)
        {
            Title = title;
            Content = content;
        }

        public string Title { get; set; }
        public string Content { get; set; }
    }
    /// <summary>
    /// 文档管理
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DocumentManager<T> where T : IDocument
    {
        //定义存储集合
        private readonly Queue<T> documentQueue = new Queue<T>();
        /// <summary>
        /// 对集合进行添值操作
        /// </summary>
        /// <param name="doc"></param>
        public void AddDocument(T doc)
        {
            lock (this)
            {
                documentQueue.Enqueue(doc);
            }
        }
        public bool IsDocumentAvailable => documentQueue.Count > 0;

        public T GetDocument()
        {
            T doc = default(T);
            lock (this)
            {
                doc = documentQueue.Dequeue();
            }
            return doc;
        }
        public void DisplayAllDocuments()
        {
            foreach (T doc in documentQueue)
            {
                Console.WriteLine(doc.Title);
            }
        }
    }
    /// <summary>
    /// 文档执行过程
    /// </summary>
    public class ProcessDocuments
    {
        private DocumentManager<Document> _documentManager;
        /// <summary>
        /// Start方法访问
        /// </summary>
        /// <param name="dm"></param>
        public static void Start(DocumentManager<Document> dm)
        {
            //对线程池上指定工作排队,并返回函数对应的任务代理
            Task.Run(new ProcessDocuments(dm).Run);
        }
        protected ProcessDocuments(DocumentManager<Document> dm)
        {
            if (dm == null)
            {
                throw new ArgumentNullException(nameof(dm));
            }
            _documentManager = dm;
        }
        /// <summary>
        /// 无限循环取队列中的信息
        /// </summary>
        /// <returns></returns>
        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));
            }
        }
    }
    //调用方式
     var dm = new DocumentManager<Document>();
     ProcessDocuments.Start(dm);
     for (int i = 0; i < 10; i++)
     {
         var doc = new Document($"Doc {i.ToString()}", "content");
         dm.AddDocument(doc);
         Console.WriteLine($"Added document {doc.Title}");
         Thread.Sleep(new Random().Next(20));
     }
     Console.ReadLine();

猜你喜欢

转载自blog.csdn.net/qq_31975127/article/details/85262895