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

@陳卧龍的博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM