温习Queue<T>
1、简述Queue<T>
Queue<T>是一个先进先出的集合,队列中先添加的元素会被先读取,比如打印队列就是这样的机制。
Queue<T>实现了接口ICollection和IEnumeratable接口,Queue<T>提供了三种常用的方法:Enque()、Deque()、Peek()。Deque()方法返回队列中的开头对象,并且删除该对象。Enque()方法是在队列的尾部添加元素。Peek()方法返回队列中第一个对象,但是并不删除。
2、一个文档管理的应用程序。使用一个线程把文档添加到队列中,用另外一个线程从队列中读取他们,并且处理它们。
①定义一个Document的类,该类定义了标题和内容。这个类很简单,代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace TestQueue 6 { 7 public class Document 8 { 9 private string tittle; 10 11 public string Tittle 12 { 13 get { return tittle; } 14 } 15 16 private string content; 17 18 public string Content 19 { 20 get { return content; } 21 } 22 23 public Document(string tittle, string content) 24 { 25 this.tittle = tittle; 26 this.content = content; 27 } 28 } 29 }
②添加DocumentManage类。
改类负责处理文档的方式。用AddDocument()方法把文档添加到队列中,GetDocument()方法获取队列中第一个文档。
代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace TestQueue 6 { 7 public class DocumentManage 8 { 9 //实例化一个泛型实例 10 private readonly Queue<Document> documentQueue = new Queue<Document>(); 11 12 //把文档添加到队列的尾部 13 public void AddDocument(Document doc) 14 { 15 lock(this){ 16 documentQueue.Enqueue(doc); 17 }; 18 } 19 20 //从队列中获取第一个文档并且移除该文档 21 public Document GetDocument() 22 { 23 Document doc = null; 24 lock (this) 25 { 26 doc = documentQueue.Dequeue(); 27 } 28 29 return doc; 30 } 31 32 //制度布尔型,如果队列中还有文档,就返回True 33 public bool IsDocumentAvailable 34 { 35 get { 36 return documentQueue.Count > 0; 37 } 38 } 39 } 40 }
③添加ProcessDocuments类。
该类在一个独立的 线程中处理队列中的文档。唯一一个可以从外部进行访问的方法是Start()方法。实例化一个新的线程。在创建一个ProcessDocuments对象,来启动线程。把Run()方法定义为线程启动的方法。ThreadStart是一个委托,它引用由线程启动的方法,如下面截图中的红色部分,在创建好Thread对象之后,就调用Thread.Start()方法启动线程。
代码如下:
1 using System; 2 using System.Threading; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace TestQueue 7 { 8 public class ProcessDocuments 9 { 10 private DocumentManage documentManage; 11 12 //显式定义一个带参数的构造函数 13 protected ProcessDocuments(DocumentManage dm) 14 { 15 documentManage = dm; 16 } 17 18 //定义一个无限循环,在这个循环中,使用属性IsDocumentAvailable判断队列中是否还有文档,如果有读取文档并处理 19 protected void Run() 20 { 21 while (true) 22 { 23 if (documentManage.IsDocumentAvailable) 24 { 25 Document doc = documentManage.GetDocument(); 26 Console.WriteLine("Process Document{0}", doc.Tittle); 27 } 28 29 Thread.Sleep(new Random().Next(20)); 30 } 31 } 32 33 //实例化一个新的线程 34 public static void Start(DocumentManage dm) 35 { 36 new Thread(new ProcessDocuments(dm).Run).Start(); 37 } 38 }
④应用程序的Main()方法。
实例化了一个DocumentManage对象,并启动文档处理线程。接着创建1000个文档,添加到DocumentManage对象中去。
代码如下:
using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace TestQueue { class Program { static void Main(string[] args) { DocumentManage dm = new DocumentManage(); ProcessDocuments.Start(dm); for (int i = 0; i < 1000; i++) { Document doc = new Document("Doc" + i.ToString(), "content"); dm.AddDocument(doc); Console.WriteLine("添加了文档{0}", doc.Tittle); Thread.Sleep(new Random().Next(20)); } Console.WriteLine("条数:{0}", dm.IsDocumentAvailable); } } }
运行结果截图: