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,计算继续进行。


 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值