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; } }
@陈卧龙的博客