下面采用两种不同的方式实现了一个简单对流水线工作进行控制程序:While循环方式和Callback回调方式:
程序运用C#实现,操作方式:先打开总的控制开关,然后点击启动工作程序就会开始工作。点击暂停则工作会暂停并可以进行恢复。工作时,同时在界面上进行操作(如点击按钮,更新显示)不会出现程序卡死现象。
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //While循环方式 Application.Run(new FormWhile()); //线程回调方式 //Application.Run(new FormCallback()); } } }
using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class FormWhile : Form { //开关信号 bool _startRun; //暂停信号 bool _waitTag; //输出信息 int outPut; public FormWhile() { InitializeComponent(); //开关默认关闭 _startRun = false; //开始工作按钮默认不显示 btnStart.Enabled = false; //暂停按钮默认不显示 btnWait.Enabled = false; //暂停信号默认为“未暂停” _waitTag = false; //输出信息值默认为0 outPut = 0; } //开始工作按钮 private void btnStart_Click(object sender, EventArgs e) { //点击开始工作后就立刻隐藏该按钮,防止重复点击 btnStart.Enabled = false; //点击开始工作后,显示暂停按钮 btnWait.Enabled = true; //让控制开关按钮获得焦点 btnSwitch.Focus(); //刷新界面 Application.DoEvents(); while (_startRun) { if (!_waitTag) { tbOutput.Text = string.Format("{0} {1}{2}{3}", DateTime.Now.ToString("hh:MM:ss"), outPut++, Environment.NewLine, tbOutput.Text); } //必须放到if(!_waitTag)的外面 //否则_waitTag的值被修改后,这里无法被通知到 Application.DoEvents(); } } //暂停按钮 private void btnWait_Click(object sender, EventArgs e) { //切换暂停状态 _waitTag = !_waitTag; //切换暂停按钮的显示名称 btnWait.Text = btnWait.Text == "暂停" ? "恢复" : "暂停"; } //控制开关按钮 private void btnSwitch_Click(object sender, EventArgs e) { //切换开关控制信号 _startRun = !_startRun; //切换开关按钮的显示名称 btnSwitch.Text = _startRun ? "关闭" : "打开"; //开关打开后显示“开始工作按钮”,否则不显示 btnStart.Enabled = _startRun ? true : false; //打开/关闭开关时,“暂停按钮”都应该是不显示的 btnWait.Enabled = false; //“暂停按钮”显示为“暂停” btnWait.Text = "暂停"; //打开/关闭开关时,都是“未暂停状态” _waitTag = false; } } }
using System; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class FormCallback : Form { //开关信号 bool _startRun; //暂停信号 bool _waitTag; //输出信息 int outPut; delegate bool TestDelegate(double d); TestDelegate testMethod = null; public FormCallback() { InitializeComponent(); //开关默认关闭 _startRun = false; //开始工作按钮默认不显示 btnStart.Enabled = false; //暂停按钮默认不显示 btnWait.Enabled = false; //暂停信号默认为“未暂停” _waitTag = false; //输出信息值默认为0 outPut = 0; } //开始工作按钮 private void btnStart_Click(object sender, EventArgs e) { //点击开始工作后就立刻隐藏该按钮,防止重复点击 btnStart.Enabled = false; //点击开始工作后,显示暂停按钮 btnWait.Enabled = true; //让控制开关按钮获得焦点 btnSwitch.Focus(); //刷新界面 Application.DoEvents(); //开始处理卡片 ManagerHandler(); } //暂停按钮 private void btnWait_Click(object sender, EventArgs e) { //切换暂停状态 _waitTag = !_waitTag; //切换暂停按钮的显示名称 btnWait.Text = btnWait.Text == "暂停" ? "恢复" : "暂停"; } //控制开关按钮 private void btnSwitch_Click(object sender, EventArgs e) { //切换开关控制信号 _startRun = !_startRun; //切换开关按钮的显示名称 btnSwitch.Text = _startRun ? "关闭" : "打开"; //开关打开后显示“开始工作按钮”,否则不显示 btnStart.Enabled = _startRun ? true : false; //打开/关闭开关时,“暂停按钮”都应该是不显示的 btnWait.Enabled = false; //“暂停按钮”显示为“暂停” btnWait.Text = "暂停"; //打开/关闭开关时,都是“未暂停状态” _waitTag = false; } //工作管理器 public void ManagerHandler() { if (_startRun) { testMethod = new TestDelegate(WorkProcess); IAsyncResult reuslt = testMethod.BeginInvoke(1.0, new AsyncCallback(WorkFinished), null); //启动新线程来处理 //ThreadStart threadStart = new ThreadStart(test); //th = new Thread(threadStart); //th.Start(); //Application.DoEvents(); } } //工作逻辑 public bool WorkProcess(double d) { try { if (!_waitTag) { //Thread.Sleep(TimeSpan.FromSeconds(1)); this.Invoke((EventHandler)(delegate { tbOutput.Text = string.Format("{0} {1}{2}{3}", DateTime.Now.ToString("hh:MM:ss"), outPut++, Environment.NewLine, tbOutput.Text); })); return true; } return false; } catch (Exception ex) { return false; } } //回调函数 public void WorkFinished(IAsyncResult result) { bool re = testMethod.EndInvoke(result); //处理下一张卡片 ManagerHandler(); } } }
界面如图所示: