C# 定时器和队列结合,卖包子啦,Timer、 AutoResetEvent、 ManualResetEvent

再你们得到源码之前,我先做个广告:张家港杰德机械/张家港三兴华轩机械是我一朋友的公司,希望需要做净水,灌装机,拔盖机,封口机,传送带等的朋友光顾。

张家港杰德机械有限公司:http://www.jiedejx.com

张家港三兴华轩机械厂:http://huaxuancch.com

OK ,开始卖包子

本程序用到队列,定时器,很简单,没什么好说的,因为用得到,所以作个记录:

如下:

    class Program
    {
        /// <summary>
        /// 本篇示例 讲解C#队列 入队  和  定时出队,例如:早上排队买包子 设置为每隔五秒,买包子成功排队的人出队!
        /// </summary>
        /// <param name="args">@陈卧龙 张家港杰德机械、张家港华轩机械:http://www.huaxuancch.com    http://www.jiedejx.com </param>
        
        /// <summary>
        /// 全局队列
        /// </summary>
        public static ConcurrentQueue<Person> _ConcurrenPersons = new ConcurrentQueue<Person>();
        static void Main(string[] args)
        {
            //模拟入队
            Person model1 = new Person("宋江", "", 66);
            Person model2 = new Person("李逵", "", 53);
            Person model3 = new Person("顾大嫂", "", 46);
            Person model4 = new Person("扈三娘", "", 46);
            Person model5 = new Person("一丈青", "", 36);
            Person model6 = new Person("林冲", "", 45);
            Person model7 = new Person("武松", "", 42);
            Person model8 = new Person("花和尚", "", 39);
            List<Person> listPerson = new List<Person>();
            listPerson.Add(model1);
            listPerson.Add(model2);
            listPerson.Add(model3);
            listPerson.Add(model4);
            listPerson.Add(model5);
            listPerson.Add(model6);
            listPerson.Add(model7);
            listPerson.Add(model8);
            foreach (var item in listPerson)
            {
                //开始排队
                PersonEnqueue(item);
            }
            //排队完成
            //
            //注册Timer 在web项目中可以在  ApplicationStart  或者   静态构造函数中注册
            Time_Task.Instance().ExecuteTask += new System.Timers.ElapsedEventHandler(ExecuteTask);
            Time_Task.Instance().Interval = 1000 * 5;//表示间隔  5秒钟执行一次
            Time_Task.Instance().Start();
            //
            Console.WriteLine("店小二:都别吵,都别吵,再等五秒钟开始卖包子。5 4 3 2 1 ...");
            Console.ReadKey();
        }


        /// <summary>
        /// 入队
        /// </summary>
        public static void PersonEnqueue(Person Model)
        {
            _ConcurrenPersons.Enqueue(Model);
        }

        /// <summary>
        /// 定时执行出队操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void ExecuteTask(object sender, System.Timers.ElapsedEventArgs e)
        {
           PersonDequeue();
        }

        /// <summary>
        /// 出队
        /// </summary>
        public static void PersonDequeue()
        {
            if (_ConcurrenPersons.Count > 0)
            {
                bool dequeueSuccesful = false;
                bool peekSuccesful = false;
                Person workItem;

                peekSuccesful = _ConcurrenPersons.TryPeek(out workItem);

                if (peekSuccesful)
                {
                    dequeueSuccesful = _ConcurrenPersons.TryDequeue(out workItem);//出队
                    Console.WriteLine("大家好,我叫" + workItem.uName + ",今年" + workItem.uAge + "岁,一大早的就叫老子排队买包子,总算买完了!" + "        " + DateTime.Now);
                }
            }
            else
            {
                Console.WriteLine("队列里没人了............");
            }
        }
    }

    public class Time_Task
    {
        public event System.Timers.ElapsedEventHandler ExecuteTask;

        private static readonly Time_Task _task = null;
        private System.Timers.Timer _timer = null;


        //定义时间
        private int _interval = 1000*5;
        public int Interval
        {
            set
            {
                _interval = value;
            }
            get
            {
                return _interval;
            }
        }

        static Time_Task()
        {
            _task = new Time_Task();
        }

        public static Time_Task Instance()
        {
            return _task;
        }

        //开始
        public void Start()
        {
            if (_timer == null)
            {
                _timer = new System.Timers.Timer(_interval);
                _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
                _timer.Enabled = true;
                _timer.Start();
            }
        }

        protected void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (null != ExecuteTask)
            {
                ExecuteTask(sender, e);
            }
        }

        //停止
        public void Stop()
        {
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Dispose();
                _timer = null;
            }
        }

    }

    /// <summary>
    /// 排队的人实体
    /// </summary>
    public class Person
    {
        public Person(string N,string S,int A)
        {
            uName = N;
            uSex = S;
            uAge = A;
        }
        public string uName { get; set; }
        public string uSex { get; set; }
        public int uAge { get; set; }
    }

@陈卧龙的博客

未完持续......

如果我们换种思路,定时器一秒钟执行一次,但,每次卖包子用时还是五秒,我们应当怎么办?这样修改的好处时,用户来了,就可以直接买包子,而不用多等五秒,同理,这一波买包子的人走了后,后续来的人也不需要多等待这个五秒!

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test2
{
    class Program
    {
        /// <summary>
        /// 本篇示例 讲解C#队列 入队  和  定时出队,例如:早上排队买包子 设置为每隔五秒,买包子成功排队的人出队!
        /// </summary>
        /// <param name="args">@陈卧龙 张家港杰德机械、张家港华轩机械:http://www.huaxuancch.com    http://www.jiedejx.com </param>
        
        /// <summary>
        /// 全局队列
        /// </summary>
        public static ConcurrentQueue<Person> _ConcurrenPersons = new ConcurrentQueue<Person>();

        static Program()
        {
            Time_Task.Instance().ExecuteTask += new System.Timers.ElapsedEventHandler(ExecuteTask);
            Time_Task.Instance().Interval = 1000 * 1;//修改成每隔一秒执行一次
            Time_Task.Instance().Start();
        }
        static void Main(string[] args)
        {
            Console.WriteLine("店小二:都别吵,都别吵,现在马上开始卖包子 ...");
            //模拟入队
            Person model1 = new Person("宋江", "", 66);
            Person model2 = new Person("李逵", "", 53);
            Person model3 = new Person("顾大嫂", "", 46);
            Person model4 = new Person("扈三娘", "", 46);
            Person model5 = new Person("一丈青", "", 36);
            Person model6 = new Person("林冲", "", 45);
            Person model7 = new Person("武松", "", 42);
            Person model8 = new Person("花和尚", "", 39);
            List<Person> listPerson = new List<Person>();
            listPerson.Add(model1);
            listPerson.Add(model2);
            listPerson.Add(model3);
            listPerson.Add(model4);
            listPerson.Add(model5);
            listPerson.Add(model6);
            listPerson.Add(model7);
            listPerson.Add(model8);
            foreach (var item in listPerson)
            {
                //开始排队
                PersonEnqueue(item);
            }
            //排队完成
          
            Console.ReadKey();
        }


        /// <summary>
        /// 入队
        /// </summary>
        public static void PersonEnqueue(Person Model)
        {
            _ConcurrenPersons.Enqueue(Model);
        }

        /// <summary>
        /// 定时执行出队操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void ExecuteTask(object sender, System.Timers.ElapsedEventArgs e)
        {
           PersonDequeue();
        }

        /// <summary>
        /// 出队
        /// </summary>
        public static void PersonDequeue()
        {
            if (_ConcurrenPersons.Count > 0)
            {
                bool dequeueSuccesful = false;
                bool peekSuccesful = false;
                Person workItem;
                 Time_Task.Instance().Stop();
                peekSuccesful = _ConcurrenPersons.TryPeek(out workItem);

                if (peekSuccesful)
                {
                    Console.WriteLine("大家好,我叫" + workItem.uName + ",今年" + workItem.uAge + "岁,一大早的就叫老子排队买包子,总算买完了!" + "        " + DateTime.Now);
                    Thread.Sleep(4000); 
                    dequeueSuccesful = _ConcurrenPersons.TryDequeue(out workItem);//出队
                }
                Time_Task.Instance().Start();
            }
            else
            {
                Console.WriteLine("队列里没人了,我要关闭定时器啦............");
                Time_Task.Instance().Stop();
            }
        }
    }

    public class Time_Task
    {
        public event System.Timers.ElapsedEventHandler ExecuteTask;

        private static readonly Time_Task _task = null;
        private System.Timers.Timer _timer = null;


        //定义时间
        private int _interval = 1000*5;
        public int Interval
        {
            set
            {
                _interval = value;
            }
            get
            {
                return _interval;
            }
        }

        static Time_Task()
        {
            _task = new Time_Task();
        }

        public static Time_Task Instance()
        {
            return _task;
        }

        //开始
        public void Start()
        {
            if (_timer == null)
            {
                _timer = new System.Timers.Timer(_interval);
                _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
                _timer.Enabled = true;
                _timer.Start();
            }
        }

        protected void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (null != ExecuteTask)
            {
                ExecuteTask(sender, e);
            }
        }

        //停止
        public void Stop()
        {
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Dispose();
                _timer = null;
            }
        }

    }

    /// <summary>
    /// 排队的人实体
    /// </summary>
    public class Person
    {
        public Person(string N,string S,int A)
        {
            uName = N;
            uSex = S;
            uAge = A;
        }
        public string uName { get; set; }
        public string uSex { get; set; }
        public int uAge { get; set; }
    }
}

案例2,如下:又来了一波买包子的人,

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test2
{
    class Program
    {
        /// <summary>
        /// 本篇示例 讲解C#队列 入队  和  定时出队,例如:早上排队买包子 设置为每隔五秒,买包子成功排队的人出队!
        /// </summary>
        /// <param name="args">@陈卧龙 张家港杰德机械、张家港华轩机械:http://www.huaxuancch.com    http://www.jiedejx.com </param>
        
        /// <summary>
        /// 全局队列
        /// </summary>
        public static ConcurrentQueue<Person> _ConcurrenPersons = new ConcurrentQueue<Person>();

        static Program()
        {
            Time_Task.Instance().ExecuteTask += new System.Timers.ElapsedEventHandler(ExecuteTask);
            Time_Task.Instance().Interval = 1000 * 1;//修改成每隔一秒执行一次
            Time_Task.Instance().Start();
        }
        static void Main(string[] args)
        {
            Console.WriteLine("店小二:都别吵,都别吵,现在马上开始卖包子 ...");
            //模拟入队
            Person model1 = new Person("宋江", "", 66);
            Person model2 = new Person("李逵", "", 53);
            List<Person> listPerson = new List<Person>();
            listPerson.Add(model1);
            listPerson.Add(model2);
            foreach (var item in listPerson)
            {
                //开始排队
                PersonEnqueue(item);
            }
            //排队完成
            Thread.Sleep(15000);
            AginEnque();// 又来了一波买包子的人
            Console.ReadKey();
        }

        /// <summary>
        /// 又来了一波买包子的人
        /// </summary>
        public  static void AginEnque()
        {
            Console.WriteLine("又有一波买包子的人来了......");
            List<Person> listPerson = new List<Person>();
            listPerson.Clear();
            Person model1 = new Person("刘备", "", 66);
            Person model2 = new Person("关羽", "", 66);
            Person model3 = new Person("张飞", "", 66);
            listPerson.Add(model1);
            listPerson.Add(model2);
            listPerson.Add(model3);
            foreach (var item in listPerson)
            {
                //第二次开始排队
                PersonEnqueue(item);
            }
            Time_Task.Instance().Start();
        }


        /// <summary>
        /// 入队
        /// </summary>
        public static void PersonEnqueue(Person Model)
        {
            _ConcurrenPersons.Enqueue(Model);
        }

        /// <summary>
        /// 定时执行出队操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void ExecuteTask(object sender, System.Timers.ElapsedEventArgs e)
        {
           PersonDequeue();
        }

        /// <summary>
        /// 出队
        /// </summary>
        public static void PersonDequeue()
        {
            if (_ConcurrenPersons.Count > 0)
            {
                bool dequeueSuccesful = false;
                bool peekSuccesful = false;
                Person workItem;
                 Time_Task.Instance().Stop();
                peekSuccesful = _ConcurrenPersons.TryPeek(out workItem);

                if (peekSuccesful)
                {
                    Console.WriteLine("大家好,我叫" + workItem.uName + ",今年" + workItem.uAge + "岁,一大早的就叫老子排队买包子,总算买完了!" + "        " + DateTime.Now);
                    Thread.Sleep(4000); 
                    dequeueSuccesful = _ConcurrenPersons.TryDequeue(out workItem);//出队
                }
                Time_Task.Instance().Start();
            }
            else
            {
                Console.WriteLine("队列里没人了,我要关闭定时器啦............");
                Time_Task.Instance().Stop();
            }
        }
    }

    public class Time_Task
    {
        public event System.Timers.ElapsedEventHandler ExecuteTask;

        private static readonly Time_Task _task = null;
        private System.Timers.Timer _timer = null;


        //定义时间
        private int _interval = 1000*5;
        public int Interval
        {
            set
            {
                _interval = value;
            }
            get
            {
                return _interval;
            }
        }

        static Time_Task()
        {
            _task = new Time_Task();
        }

        public static Time_Task Instance()
        {
            return _task;
        }

        //开始
        public void Start()
        {
            if (_timer == null)
            {
                _timer = new System.Timers.Timer(_interval);
                _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
                _timer.Enabled = true;
                _timer.Start();
            }
        }

        protected void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (null != ExecuteTask)
            {
                ExecuteTask(sender, e);
            }
        }

        //停止
        public void Stop()
        {
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Dispose();
                _timer = null;
            }
        }

    }

    /// <summary>
    /// 排队的人实体
    /// </summary>
    public class Person
    {
        public Person(string N,string S,int A)
        {
            uName = N;
            uSex = S;
            uAge = A;
        }
        public string uName { get; set; }
        public string uSex { get; set; }
        public int uAge { get; set; }
    }
}

 未完持续...

如果我们不使用定时器,该怎么写呢?

不使用定时器时,我们可以使用C#的信号量机制,所谓信号量机制请参考鄙人写的博客:C#深入理解AutoResetEvent和ManualResetEvent 。

具体怎么实现,看下面代码:

    class Program
    {
        /// <summary>
        /// 本篇示例 讲解C#队列 入队  和  定时出队,例如:早上排队买包子 设置为每隔五秒,买包子成功排队的人出队!
        /// </summary>
        /// <param name="args">@陈卧龙 张家港杰德机械、张家港华轩机械:http://www.huaxuancch.com    http://www.jiedejx.com </param>

        /// <summary>
        /// 全局队列
        /// </summary>
        public static ConcurrentQueue<Person> _ConcurrenPersons = new ConcurrentQueue<Person>();
        static AutoResetEvent myResetEvent = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            Console.WriteLine("店小二:都别吵,都别吵,再等五秒钟开始卖包子。5 4 3 2 1 ...");
            Thread thread = new Thread(PersonDequeue);
            thread.Name = "queue";
            thread.Start();
            //模拟入队
            Person model1 = new Person("宋江", "", 66);
            Person model2 = new Person("李逵", "", 53);
            
            List<Person> listPerson = new List<Person>();
            listPerson.Add(model1);
            listPerson.Add(model2);
            foreach (var item in listPerson)
            {
                //开始排队
                PersonEnqueue(item);
            }
            //
           
            Console.ReadKey();
        }


        /// <summary>
        /// 入队
        /// </summary>
        public static void PersonEnqueue(Person Model)
        {
            _ConcurrenPersons.Enqueue(Model);

            myResetEvent.Set();
            Thread.Sleep(2000);
        }

        /// <summary>
        /// 出队
        /// </summary>
        public static void PersonDequeue()
        {
            while (true)
            {
                myResetEvent.WaitOne();
                if (_ConcurrenPersons.Count > 0)
                {
                    bool dequeueSuccesful = false;
                    bool peekSuccesful = false;
                    Person workItem;

                    peekSuccesful = _ConcurrenPersons.TryPeek(out workItem);

                    if (peekSuccesful)
                    {
                        dequeueSuccesful = _ConcurrenPersons.TryDequeue(out workItem);//出队
                        Console.WriteLine("大家好,我叫" + workItem.uName + ",今年" + workItem.uAge + "岁,一大早的就叫老子排队买包子,总算买完了!" + "        " + DateTime.Now);
                    }
                }
                else
                {
                    Console.WriteLine("队列里没人了............");

                }
            }
        }
    }

    /// <summary>
    /// 排队的人实体
    /// </summary>
    public class Person
    {
        public Person(string N, string S, int A)
        {
            uName = N;
            uSex = S;
            uAge = A;
        }
        public string uName { get; set; }
        public string uSex { get; set; }
        public int uAge { get; set; }
    }

@陈卧龙的博客

posted @ 2017-05-11 11:54  天才卧龙  阅读(2872)  评论(1编辑  收藏  举报