C#中队列集合的用法,配合线程

来源:互联网 发布:淘宝盗图处罚规则新规 编辑:程序博客网 时间:2024/05/16 09:54
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. namespace 集合
  7. {
  8.     class 队列
  9.     {
  10.         public static void Main()
  11.         { 
  12.             //队列: 元素以先进先出的方式来处理的集合(FIFO-First In First Out)第一个来,第一个滚
  13.             //例:飞机登记排队,靠前的就先上飞要,不过队列有优先级,如商务仓的队与经济仓的队,是两个不同的队,而商务优先
  14.             //在.Net技术中,      using System.Collections.Generic.Queue<T>是队列的泛型版本实现
  15.             // System.Collections.Queue是非泛型的实现,参数是Object
  16.             //public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable
  17.             //从队列的定义可以看出,它实现了跌代,集合接口 ,它没有实现ICollection<T>这个接口,因为其中定义的Add Remove方法会破坏队列
  18.             //队列与列表主要区别就是在于,它没有实现IList接口
  19.             //所以,不可以用索引器访问队列,队列只允许添加元素,该元素只能放在队列的最后(Enqueue()),还有就是从头部取元素Dequeue()
  20.             //Enqueue从队列的后面插入元素,而 Dequeue在取一个元素的同时,会前取出的元素删除,如再再调用一次,就删除下一个元素
  21.             
  22.             //方法简介 :
  23.             // Enqueue() 一端插入元素
  24.             // Dequeue() 从头部读取和删除一个元素,如果调用方法时,队列中没有元素,刨出InvalidOperationException异常
  25.             // Peek() 在队列头部读取一个元素,但是,不删除它
  26.             // Count 返回队列元素个数
  27.             // TrimExcess() 重新设置队列容量,Dequeue方法,是可能删除一个对象,但是,不会重设容量,这样会浪费空余空间 ,本方法,从头部清除空余空间
  28.             // Contains() 确定某个元素是不是在队列中,如果是,返回true
  29.             // CopyTo() 把元素从队列复制到一个已有的数组中 
  30.             // ToArray() 返回一个包含队列元素的新数组
  31.             // 下面我们开始写一个关于队列的例子, 使用一个线程将文档添加到队列中,用另一个线程读取队列,并处理他们
  32.             // 存储队列的类型是Document,我们先定义一个文档类,接着定义一个文档处理类DocumentManager,其中包含了添加与读取方法,还有一个属性确定队列中是不是为空
  33.             // 然后我们定义一个 ProcessDocuments来处理线程,操作文档
  34.            
  35.             DocumentManager mg = new DocumentManager();
  36.             ProcessDocuments prcess = new ProcessDocuments( mg );
  37.             //启动读取线程,不过现在没内容,要等一会加入后,就能读到了
  38.             ProcessDocuments.Start(mg);
  39.             Document doc = null;
  40.             for (int i = 0; i < 500; i++)
  41.             {
  42.                 doc = new Document("Aladdin:" + i, "Hello,Nihao!");
  43.                 mg.AddDocument( doc );
  44.                 //睡会,让给其他线程玩会
  45.                 //Thread.Sleep(20);
  46.             }
  47.             Console.ReadLine();
  48.         }
  49.     }
  50.     
  51.     // 文档类,描述了文档的标题与内容
  52.     class Document
  53.     {
  54.         public string title;
  55.         public string content;
  56.         public Document(string title, string content)
  57.         {
  58.             this.title = title;
  59.             this.content = content;
  60.         }
  61.     }
  62.     class DocumentManager
  63.     {
  64.         //定义队列集合
  65.         private readonly Queue<Document> docQueue = new Queue<Document>();
  66.         
  67.         //添加文档
  68.         public void AddDocument(Document doc)
  69.         {
  70.             lock (this)
  71.             {
  72.                 //从队列一端插入内容
  73.                 docQueue.Enqueue(doc);
  74.                 Console.WriteLine( "成功插入文档:" + doc.title);
  75.             }
  76.         }
  77.         
  78.         //读取文档
  79.         public Document GetDocument()
  80.         {
  81.             Document doc = null;
  82.             lock (this)
  83.             {
  84.                 doc = docQueue.Dequeue();
  85.                 return doc;
  86.             }
  87.         }
  88.         //只读属性,确定队列中是不是还有元素
  89.         public bool IsDocumentAvailable
  90.         {
  91.             get
  92.             {
  93.                 return docQueue.Count > 0;
  94.             }
  95.         }
  96.     }
  97.     // 处理文档
  98.     class ProcessDocuments
  99.     {
  100.         private DocumentManager dm;
  101.         public ProcessDocuments( DocumentManager dm )
  102.         {
  103.             this.dm = dm;
  104.         }
  105.         public static void Start(DocumentManager manager)
  106.         { 
  107.             // 参数 : public delegate void ThreadStart();
  108.             new Thread(new ProcessDocuments(manager).DoThreadFunc).Start() ;
  109.         }
  110.         public void DoThreadFunc()
  111.         { 
  112.             //无限循环读取,只要队列中有内容,这条线程就读出来
  113.             while (true)
  114.             {
  115.                 if (this.dm.IsDocumentAvailable)
  116.                 {
  117.                     Document doc = this.dm.GetDocument() ;
  118.                     Console.WriteLine("从队列中读到读取并删除文档 标题:{0}   内容: {1}", doc.title, doc.content );
  119.                 }
  120.             }
  121.         }
  122.     }
  123. }
原创粉丝点击