Winform利用多线程、委托、invoke解决界面卡死问题

假设在winform中有如下代码:

private void button1_Click(object sender, EventArgs e)    
    {       
            int i = 0;
            while (true)
            {
                i = i + 2;
                richTextBox1.AppendText(i.ToString() + "\r\n");
                richTextBox1.ScrollToCaret();

            }
        ...
     }

则程序运行后会出现界面卡死无法响应操作的现象,如何解决?

首先,在窗体内建立一个成员方法来实现上述代码中的显示功能:

private  void ShowMessage(string message)
        {
            richTextBox1.AppendText(message + "\r\n");
            richTextBox1.ScrollToCaret();
        }

其次,在窗体中创建一个形参与上述ShowMessage方法相同的委托并实例化一个对象,同时创建一个线程对象(需引入 System.Threadding空间);,如下:

 public partial class Form1 : Form
    {
        delegate void MyDelegate(string message);
        private  MyDelegate myDeleteage;
        private Thread thread;
        ......

接着,在窗体的Form_Load事件增加一名代码,将显示方法搭载到委托对象上,如下:

        private void Form1_Load(object sender, EventArgs e)
        {
            myDeleteage = ShowMessage;
        }

然后,将前述的计算代码改写成一个窗体的成员方法。

private void Caculate()
        {
            int i = 0;
            while(true)
            {
                i = i + 2;
                this.Invoke(myDeleteage, i.ToString());
            }
        }

注意,这里使用了Invoke方法,可以这样理解,当需要显示时,由窗体的Invoke方法调用委托对象,并将要显示的内容传递给委托对象。而由于委托对象搭载了ShowMessage方法,所以执行this.Invoke(myDeleteage, i.ToString())语句时,实际是执行了ShowMessage(i.ToString())语句。

最后,在窗体中增加两个按钮,其单击事件代码分别如下:

 private void button1_Click(object sender, EventArgs e)
        {

            this.Invoke(myDeleteage, "begin to calculate...");
            button1.Enabled = false;
            button2.Enabled = true;
            if (thread == null)
            {
                thread = new Thread(Calculate);
                thread.Start();
            }
            if (thread.ThreadState == ThreadState.Suspended)
            {
                thread.Resume();
            }
        }
private void button2_Click(object sender, EventArgs e)
        {
           
            button2.Enabled = false;
            thread.Suspend();
            this.Invoke(myDeleteage, "Calculating is stoped.");
            button1.Enabled = true;

        }

运行程序,单击button1,计算结果源源不断显示在文本框内,且界面没有卡死,单击button2,计算被暂停,再单击button1,计算继续进行。


 

你可能感兴趣的:(winForm,winform,界面,卡死,委托,invoke)