zoukankan      html  css  js  c++  java
  • 用队列来处理订单以及集合间性能比较

    数组的大小是固定的,如果元素个数是动态的,就应使用集合类,集合可以根据集合类实现的接口组合为列表、集合和字典,集合实现的常用接口有如下

    (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

  • 相关阅读:
    【服务器】【Windows】【3】开放服务器端口
    【服务器】【Windows】【2】把jar包做成服务,在Service中管理
    FZU 1753
    poj 1017
    poj 1666
    poj 1132
    ZOJ 2562 More Divisors
    POJ 2992 Divisors
    poj 2773 happy 2006
    poj 2407 Relatives
  • 原文地址:https://www.cnblogs.com/simen-tan/p/6974148.html
Copyright © 2011-2022 走看看