C#后台线程更新窗体界面的示例

当我们的程序达到一定的复杂度之后,有时需要一个后台进程来处理一些数据,而窗体界面显示数据的变化,而又不能进入假死状态,或是某个进程比较耗时,需要等待,比如网络传输数据,此时,使用线程处理是必不可少的一种方法。对于初学者来说,如何让后台线程与界面配合使用,是不太容易理解的,如果你能熟练使用这种方法,将会带你迈入程序开发的一个新的阶段,基于此可以解决很多类似问题。

为此,作为初学者的我,经过摸索,把所得的一段代码或者说是一种方法分享出来,希望能给大家一些启发,并希望能相互学习,有什么问题,希望得到大家的指正。当然,可能还有更优雅更完美的方法,有待进一步摸索。

示例假定在一个窗体上,有3个textbox,1个button,当按下button时,依次向textbox填入一些随机值。

对于这类问题,我们首先比较清楚的,简单来说会有两个函数:一个是后台数据处理函数,一个是界面更新的函数,这两个函数直接关联,则会出现假死,如果把第一个函数放置在线程中,直接调用第二个函数,则界面是不允许更新的,此时,必须使用代理,或者说是一种间接的方式。

可能我的表述不十分准确,具体请参考代码:(代码中的某些文字的表述,名词可能不太准确,但可能这样去理解。)

    public partial class Form1 : Form
    {
        Random rd = new Random();
        string sa, sb, sc;                   //定义全局数据,这些数据由后台线程和前端界面共享,免去参数传递的麻烦,数据一般由后台线程更新,前端界面读取显示
        Thread thread;                       //定义一个线程
        public delegate void UpdateUI();     //定义一个代理结构
        public UpdateUI updateui;            //定义一个代理变量
        
        public Form1()
        {
            InitializeComponent();
            updateui = new UpdateUI(viewtext);        //实例化代理变量,让它与界面更新的函数相关联
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (thread == null || thread.ThreadState == ThreadState.Stopped)
            {
                thread = new Thread(process);             //实例化线程,让它与后台数据更新的函数相关联
                thread.IsBackground = true;               //将线程设置为后台线程,让它能在主程序关闭时,它能自动关闭
                thread.Start();
            }
        }

        private void process()                      //后台处理函数
        {
            int i, n;
            for (i = 0; i < 100; i++)
            {
                n = rd.Next(20);
                switch (i % 3)
                {
                    case 0:
                        sa += " " + n.ToString();
                        break;
                    case 1:
                        sb += " " + n.ToString();
                        break;
                    case 2:
                        sc += " " + n.ToString();
                        break;
                }
                this.Invoke(updateui);             //当数据发生了变化,交由代理 处理界面的更新
                Thread.Sleep(100);
            }
        }

        private void viewtext()                    //实际的界面更新函数
        {
            textBox1.Text = sa;
            textBox2.Text = sb;
            textBox3.Text = sc;
        }
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值