數組的大小是固定的,若是元素個數是動態的,就應使用集合類,集合能夠根據集合類實現的接口組合爲列表、集合和字典,集合實現的經常使用接口有以下編程
(1)IEnumerable<T>:若是將foreach語句用於集合,就須要IEnumerable接口,這個接口定義了方法GetEnumerator(),它返回了一個實現了IEnumerator接口的枚舉數組
(2)ICollection<T>:ICollection<T>接口由泛型集合類實現,使用這個接口能夠得到集合中的元素個數(Count屬性),把集合複製到數組中的方法(CopyTo()),還能夠從集合中增長刪除元素(Add(),Remove(),Clear())ide
(3)IList<T>:IList<T>接口用於可經過位置訪問其中的元素列表,這個接口定義了一個索引器,能夠在集合中的指定位置插入或則刪除某些項(Insert()和RemoveAt()方法)。IList<T>派生至ICollection<T>接口性能
(4)ISet<T>:ISet<T>接口由集實現,集容許合併不一樣的集,得到兩個集的交集,檢查兩個集是否重疊。ISet<T>接口派生自ICollection<T>接口this
(5)IDictionary<TKey,TValue>:IDictionary<TKey,TValue>接口由包含鍵和值泛型集合類實現,使用這個接口能夠訪問全部的鍵和值,使用鍵類型的索引器能夠訪問某些項,還能夠添加和刪除某些項spa
隊列是其元素以先進先出(FIFO)的方式來處理的集合。先放入隊列中的元素會先讀取,其實就是咱們在編程中遇處處理訂單的處理流程,先來的先處理,但若是考慮到不一樣訂單的優先級,咱們會優先處理優先級高的訂單,先定義一個簡單訂單實體。線程
public class ProductOrder { public string Name { get;private set; } /// <summary> /// 用於標識訂單的優先級 /// </summary> public string Level { get; private set; } public string Content { get; private set; } public ProductOrder(string name, string level, string content) { this.Name = name; this.Level = level; this.Content = content; } public override string ToString() { return string.Format("Name:{0};Level{1};Content{2}",Name,Level,Content); } }
定義一個訂單處理核心類,用於處理改訂單,改類包含兩個不一樣的隊列用戶處理不一樣優先級的訂單,定義一個BackgroundWorker類來處理隊列中的訂單。code
public class DealWithOrder { private BackgroundWorker Backwork; //用來控制工做線程 private bool isRunning = false; /// <summary> /// trigger this event when deal order /// </summary> public event Action<ProductOrder> ProgressShowEvent; private readonly Queue<ProductOrder> nomalQueue = new Queue<ProductOrder>(); private readonly Queue<ProductOrder> urgentQueue = new Queue<ProductOrder>(); public DealWithOrder(bool isdealOrder) { isRunning = isdealOrder; Backwork = new BackgroundWorker() { WorkerSupportsCancellation = true, WorkerReportsProgress = true }; Backwork.DoWork += Backwork_DoWork; Backwork.ProgressChanged += Backwork_ProgressChanged; } /// <summary> /// 開始工做線程 /// </summary> public void StartDealWithOrder() { Backwork.RunWorkerAsync(); } /// <summary> /// 沒處理完一個訂單觸發一次 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Backwork_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (!isRunning) return; switch (e.ProgressPercentage) { case 1: if (e.UserState is ProductOrder urgentOrder) ProgressShowEvent(urgentOrder); break; case 2: if (e.UserState is ProductOrder normalOrder) ProgressShowEvent(normalOrder); break; } } /// <summary> /// 工做線程處理訂單 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Backwork_DoWork(object sender, DoWorkEventArgs e) { ProductOrder rec = null; while (isRunning) { lock (this) { if (urgentQueue.Count > 0) { rec = urgentQueue.Dequeue(); Backwork.ReportProgress(1, rec); } else { if (nomalQueue.Count > 0) { rec = nomalQueue.Dequeue(); Backwork.ReportProgress(2, rec); } } } } } /// <summary> /// 正常訂單的增長 /// </summary> /// <param name="nomalOrder"></param> public void AddNomalOrder(ProductOrder nomalOrder) { lock (this) { nomalQueue.Enqueue(nomalOrder); } } /// <summary> /// 緊急訂單的增長 /// </summary> /// <param name="urgentOrder"></param> public void AddUrgentOrder(ProductOrder urgentOrder) { lock (this) { urgentQueue.Enqueue(urgentOrder); } } /// <summary> /// 是否還有未處理完的正常訂單 /// </summary> public bool IsNomalAvailable { get { return nomalQueue.Count > 0; } } /// <summary> /// 是否還有未處理完的緊急訂單 /// </summary> public bool IsUrgentAvailable { get { return urgentQueue.Count > 0; } } }
在控制檯程序中添加訂單示例,並增長對ProgressShowEvent的訂閱orm
static void Main(string[] args) { var dealWithOrder = new DealWithOrder(true); dealWithOrder.ProgressShowEvent += DealWithOrder_ProgressShowEvent; var normalOrder = new ProductOrder("Simen", "nomal", "2222"); dealWithOrder.AddNomalOrder(normalOrder); var urgentOrder = new ProductOrder("Simen", "urgent", "1111"); dealWithOrder.AddUrgentOrder(urgentOrder); dealWithOrder.StartDealWithOrder(); Console.ReadKey(); } private static void DealWithOrder_ProgressShowEvent(ProductOrder obj) { Console.WriteLine(obj); }
輸出的結果如圖blog
完成示例應用程序中描述的任務的真實程序能夠處理Web服務接收到的文檔,若是你不想用兩個隊列來實現不一樣優先級的訂單處理方式不同,能夠考慮用鏈表來實現。
許多集合都提供了相同的功能,例如,SortedList類與SortedDictionary類的功能幾乎徹底相同,可是其性能經常有很大區別,一個集合使用的內存少,另外一個集合的元素檢索速度快,譬如說在List<int>每調用一次Add()方法都要移動整個集合,下圖顯示了各類集合在執行各類方法時所用的操做時間。
其中O(1)表示不管集合有多少項,這個操做所須要的時間不變
O(log n)表示操做所須要的時間隨集合集合中的元素增長而增長,但每一個元素須要增長的時間不是線性的,而是成對稱曲線的
O(n)表示對於集合操做時間在最壞狀況下是N