1. 程式人生 > >用隊列來處理訂單以及集合間性能比較

用隊列來處理訂單以及集合間性能比較

ado 而是 div don 指定 bre 移動 edev err

數組的大小是固定的,如果元素個數是動態的,就應使用集合類,集合可以根據集合類實現的接口組合為列表、集合和字典,集合實現的常用接口有如下

(1)IEnumerable<T>:如果將foreach語句用於集合,就需要IEnumerable接口,這個接口定義了方法GetEnumerator(),它返回了一個實現了IEnumerator接口的枚舉

(2)ICollection<T>:ICollection<T>接口由泛型集合類實現,使用這個接口可以獲得集合中的元素個數(Count屬性),把集合復制到數組中的方法(CopyTo()),還可以從集合中增加刪除元素(Add(),Remove(),Clear())

(3)IList<T>:IList<T>接口用於可通過位置訪問其中的元素列表,這個接口定義了一個索引器,可以在集合中的指定位置插入或則刪除某些項(Insert()和RemoveAt()方法)。IList<T>派生至ICollection<T>接口

(4)ISet<T>:ISet<T>接口由集實現,集允許合並不同的集,獲得兩個集的交集,檢查兩個集是否重疊。ISet<T>接口派生自ICollection<T>接口

(5)IDictionary<TKey,TValue>:IDictionary<TKey,TValue>接口由包含鍵和值泛型集合類實現,使用這個接口可以訪問所有的鍵和值,使用鍵類型的索引器可以訪問某些項,還可以添加和刪除某些項

隊列是其元素以先進先出(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類來處理隊列中的訂單。

 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的訂閱

 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);
        }

輸出的結果如圖

技術分享

完成示例應用程序中描述的任務的真實程序可以處理Web服務接收到的文檔,如果你不想用兩個隊列來實現不同優先級的訂單處理方式不一樣,可以考慮用鏈表來實現。

許多集合都提供了相同的功能,例如,SortedList類與SortedDictionary類的功能幾乎完全相同,但是其性能常常有很大區別,一個集合使用的內存少,另一個集合的元素檢索速度快,譬如說在List<int>每調用一次Add()方法都要移動整個集合,下圖顯示了各種集合在執行各種方法時所用的操作時間。

技術分享

其中O(1)表示無論集合有多少項,這個操作所需要的時間不變

O(log n)表示操作所需要的時間隨集合集合中的元素增加而增加,但每個元素需要增加的時間不是線性的,而是成對稱曲線的

O(n)表示對於集合操作時間在最壞情況下是N

用隊列來處理訂單以及集合間性能比較