我是靠谱客的博主 土豪白开水,最近开发中收集的这篇文章主要介绍新版银行排队机(上),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

很早以前写过一个排队机,当时使用的是.Net1.1,使用的是Monitor来监视线程,升级到.Net2.0以后,居然一堆异常,懒得改了,重写一 个。
先说要实现的目标:银行有一堆雇员,每个雇员的窗口外有一个显示屏,显示屏上显示要处理的客户的号码,如果有客户来,那么去排队机上拿一张纸条,上面写着 他抽到的号码,如果前面人多,那么还要显示他前面还有多少人,方便客户等待,雇员开始工作后,按一下他前面的按钮,从排队队列中顺序的取其中一个号码去处 理业务,不能出现两个雇员同时按下按钮,取到同一个客户的号码,也不能有客户被遗漏,直到所有的客户都被处理完,这样雇员就每过一会去队列中看一下,有人 没,没人,继续等,有人的话,谁抢到就是谁的。
雇员类:

using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Collections; using System.Windows.Forms; using System.IO; namespace prjBankNew { public class Emp { AutoResetEvent are; /// <summary> /// 信号机 /// </summary> public AutoResetEvent Are { get { return are;} set { are = value; } } Label lbl; /// <summary> /// 雇员窗外的显示屏 /// </summary> public Label WindowNumber { get { return lbl; } set { lbl = value; } } Queue customers; /// <summary> /// 客户队列 /// </summary> public Queue Customers { get { return customers; } set { customers = value; } } /// <summary> /// 干活 /// </summary> public void ProcessCustomer() { //使劲处理,不结束。 while (true) { try { //如果不处于等待状态 if (are.WaitOne()) { //判断队列中是否有数据 if (customers.Count!=0) { //从队列中提取一个数据 string s= customers.Dequeue() as string; //写到标签里 lbl.Text = s; //如果加上这一句,那么在给标签赋值完成后3s之内不能添加新客户 //Thread.Sleep(3000); //释放控制 are.Set(); //处理数据 //记录这个雇员处理的顾客编号。 StreamWriter sw = new StreamWriter(Thread.CurrentThread.Name + "log.txt", true, Encoding.GetEncoding("gb2312")); sw.WriteLine(s); sw.Flush(); //关闭特别重要,如果不关,下次在打开的时候会引发异常。 sw.Close(); //用睡5s表示正在处理业务 Thread.Sleep(5000); } else//如果处于等待状态 { //让出控制权 are.Set(); //稍微睡一会。 //如果不在此睡一会,那么当队列中没有数据的时候 //就会使劲给标签赋值,导致CPU使用率上升。 //当然睡的时间长短,要看你要处理数据的及时性 //如果不着急,那就设置长一点,带来的后果是, //队列中已经有数据了,但是得等一会才能处理。 Thread.Sleep(1); lbl.Text = "空闲中"; } } } catch (Exception e) { //挂了以后,记录是怎么挂的。 StreamWriter sw = new StreamWriter("log.txt", true, Encoding.GetEncoding("gb2312")); sw.WriteLine(e.Message); sw.Flush(); sw.Close(); } } } } }

窗体:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Collections; using System.Threading; using System.IO; namespace prjBankNew { public partial class frmMain : Form { public frmMain() { InitializeComponent(); } // 弄一个客户队列 private Queue Customers = new Queue(); //起始号码 private int Number = 1; //弄5个雇员 Emp emp1 = new Emp(); Emp emp2 = new Emp(); Emp emp3 = new Emp(); Emp emp4 = new Emp(); Emp emp5 = new Emp(); //5个雇员用5个线程来干活。 Thread t1; Thread t2; Thread t3; Thread t4; Thread t5; //信号机,开始状态为不终止 AutoResetEvent are = new AutoResetEvent(true); private void frmMain_Load(object sender, EventArgs e) { //获得队列对象的同步版本 Customers = Queue.Synchronized(Customers); //将控制权交出去 //are.Set(); } /// <summary> /// 进来一个客户按一下按钮,取一张排队纸条 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnCustomer_Click(object sender, EventArgs e) { //排队纸条 lblCustomer.Text = "您的号码是" + Number + ",您前面有" + Customers.Count + "客户"; //如果能继续 are.WaitOne(); //向客户队列中加一个客户 Customers.Enqueue(Number.ToString()); //加完后,释放控制权 are.Set(); //号码加一 Number++; } /// <summary> /// 雇员上班开工喽 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnEmp_Click(object sender, EventArgs e) { //5个雇员使用同一个信号机 emp1.Are = are; emp2.Are = are; emp3.Are = are; emp4.Are = are; emp5.Are = are; //雇员1要处理的客户队列为大家都要处理的客户队列 emp1.Customers = Customers; //雇员1窗外的显示屏 emp1.WindowNumber = lbl1; //让线程1来处理雇员1的方法 t1 = new Thread(new ThreadStart(emp1.ProcessCustomer)); emp2.Customers = Customers; emp2.WindowNumber = lbl2; t2 = new Thread(new ThreadStart(emp2.ProcessCustomer)); emp3.Customers = Customers; emp3.WindowNumber = lbl3; t3 = new Thread(new ThreadStart(emp3.ProcessCustomer)); emp4.Customers = Customers; emp4.WindowNumber = lbl4; t4 = new Thread(new ThreadStart(emp4.ProcessCustomer)); emp5.Customers = Customers; emp5.WindowNumber = lbl5; t5 = new Thread(new ThreadStart(emp5.ProcessCustomer)); //给雇员们起个名字 t1.Name = "1号雇员"; t2.Name = "2号雇员"; t3.Name = "3号雇员"; t4.Name = "4号雇员"; t5.Name = "5号雇员"; //在窗户后面悄悄的干,别影响其他人 //如果银行关门了,那么他们才可以下班。 t1.IsBackground = true; t2.IsBackground = true; t3.IsBackground = true; t4.IsBackground = true; t5.IsBackground = true; //开工! t1.Start(); t2.Start(); t3.Start(); t4.Start(); t5.Start(); } /// <summary> /// 处理雇员的上厕所的状况 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnPause_Click(object sender, EventArgs e) { //雇员自己按一下面前的暂停按钮 if (btnPause.Text.Equals("暂停")) { t1.Suspend(); btnPause.Text = "开始"; } else { t1.Resume(); btnPause.Text = "暂停"; } } /// <summary> /// 当银行关门的时候,把雇员手头的工作都停下来。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { t1.Abort(); t2.Abort(); t3.Abort(); t4.Abort(); t5.Abort(); } private void timer1_Tick(object sender, EventArgs e) { //显示时间 this.lblTime.Text = DateTime.Now.ToString("hh:mm:ss"); //设置进度条的最大值,小于10,设置为10 //大于10,值多大,设置为多大。 this.pbCustomers.Maximum = this.Customers.Count>10?this.Customers.Count:10; //设置进度条的值 this.pbCustomers.Value = Customers.Count; //把在未处理的客户的数量写在标签上。 this.lblCount.Text = Customers.Count.ToString(); } } }

最后

以上就是土豪白开水为你收集整理的新版银行排队机(上)的全部内容,希望文章能够帮你解决新版银行排队机(上)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部