C#UI多线程编程入门

来源:互联网 发布:优先队列最短路径算法 编辑:程序博客网 时间:2024/05/17 07:46

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函数终止代码。

全文代码: 下载








原创粉丝点击