WinForm异步编程
启动异步线程
假定form中具有如下控件一个lable(lblStatus)和一个button(btnStart),并给button添加click事件。
实现异步更新方法一:
private void StatusAppend(string val) { this.lblStatus.Text += val; } private void SecondlyUpdate(object obj) { int _n = (int)obj; if (_n > 0 ) { for (int i = 0; i < _n; i++) { Thread.Sleep(1000); if (this.lblStatus.InvokeRequired == true) this.lblStatus.BeginInvoke(new Append(StatusAppend), new string[] { string.Format("{0},", i+1) }); else this.lblStatus.Text += string.Format("{0}, ", i); } MessageBox.Show("Done"); } return; } private delegate void Async(object obj); private delegate void Append(string str); private void btnStart_Click(object sender, EventArgs e) { new Async(SecondlyUpdate).BeginInvoke(3, null, null); }
实现异步更新方法二:
修改btnStart_Click函数实现为如下:
private void btnStart_Click(object sender, EventArgs e) { new Thread(() => { int i = 0; while (i++ < 5) { Thread.Sleep(1000); this.lblStatus.BeginInvoke(new Append(StatusAppend), new string[] { string.Format("{0}, ", i) }); } }).Start(); }最后结果输出结果为
停止异步线程
进一步增加难度,将给form再添加一个button(btnStop)来停止异步线程与其click事件,form如下所示。
修改代码如下所示
private Thread _t = null; private void btnStart_Click(object sender, EventArgs e) { _t = new Thread(() => { int i = 0; while (i++ < 5) { Thread.Sleep(1000); if (this.lblStatus.InvokeRequired == true) this.lblStatus.BeginInvoke(new Append(StatusAppend), new string[] { string.Format("{0}, ", i) }); else this.lblStatus.Text += string.Format("{0}, ", i); } if (this.btnStop.InvokeRequired == true) { this.btnStop.BeginInvoke((MethodInvoker)delegate() { this.btnStop.Enabled = false; }, null); } if (this.btnStart.InvokeRequired == true) { //this.btnStart.BeginInvoke((MethodInvoker)delegate() //{ // this.btnStart.Enabled = true; //}, null); this.btnStart.BeginInvoke(new Action<int>(delegate(int parm){ this.btnStart.Enabled = true; }), 1); } }); _t.IsBackground = true; _t.Start(); btnStart.Enabled = false; btnStop.Enabled = true; } private void btnStop_Click(object sender, EventArgs e) { if (_t != null) { if (_t.IsAlive == true) { _t.Abort(); lblStatus.Text = "Status: "; btnStop.Enabled = false; btnStart.Enabled = true; } } }其中添加了Thread成员变量来存储Thread对象以便在stop按钮click事件中调用abort来终止异步线程;
同时在修改了Thread中ThreadStart函数(已经匿名了),后面修改start/stop按钮的属性,同时使用了MethodInvoker以及Action来简化代码,否则需要写额外的函数以及delegate。
在stop按钮中click事件里,通过thread对象的IsAlive属性来调用Abort函数终止代码。
全文代码: 下载