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函数终止代码。
全文代码: 下载