C#多线程UpdataUI

项目场景:

多线程UpdataUI:
1.Delegate更新
2.BackgroudWorker类更新


问题描述:

简易界面如下,点击button1在线程里改变textbox1的文本,delegate可以实现所在方法循环更新。backgroudworker单次更新。
在这里插入图片描述

在线程中更新UI出现跨线程访问错误:两种方式都在下面的代码里。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ThreadWindowsFormsApplication2
{
    public delegate void mydelegate(string str);
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        System.Threading.Thread td1 = null;
        TestFuc tf = new TestFuc();
        private void button1_Click(object sender, EventArgs e)
        {
            //thread and delegate updata UI
            //td1 = new System.Threading.Thread(new System.Threading.ThreadStart(tf.Test));
            //td1.IsBackground = false;
            //tf.OnUpdateUI += updataUI1;
            //td1.Start();
            //System.Threading.Thread.Sleep(5000);
            //updataUI("ooo");


            //backgroundworker updata UI BackgroundWorker是.NET里面用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。耗时的操作(如下载和数据库事务) 
            using (BackgroundWorker bw = new BackgroundWorker())
            {
                //ctrl Updata delegate
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                //执行耗时操作的线程
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                //开始执行步骤:开始执行耗时操作的线程bw_DoWork,UI更新线程bw_RunWorkerCompleted等待,耗时操作完成,在执行UI更新线程
                bw.RunWorkerAsync("Task");
            }

        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            // 这里是后台线程, 是在另一个线程上完成的
            // 这里是真正做事的工作线程
            // 可以在这里做一些费时的,复杂的操作
            Thread.Sleep(1000);
            e.Result = e.Argument + "工作线程完成";
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了 
            this.textBox1.Text = e.Result.ToString();
        }

        /// <summary>
        /// Updata UI Methed
        /// </summary>
        /// <param name="str"></param>
        public void updataUI(string str)
        {
            if (this.InvokeRequired)
            {
                //后台线程执行走这里
                this.textBox1.BeginInvoke(new Action(() =>
                {
                    this.textBox1.AppendText(str + Environment.NewLine);
                }));
            }
            else
            {
                //主线程执行走这里
                this.textBox1.AppendText(str + Environment.NewLine);
            }
        }

        /// <summary>
        /// 委托更新UI的另外一种写法
        /// </summary>
        /// <param name="str"></param>
        public void updataUI1(string str)
        {
            //Invoke方法和BeginInvoke方法的区别是
            //Invoke方法是同步的, 它会等待工作线程完成,
            //BeginInvoke方法是异步的, 它会另起一个线程去完成工作线程
            Action act = delegate () { this.textBox1.AppendText(str + Environment.NewLine); };
            this.Invoke(act);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(td1!=null) this.td1.Abort();
        }
    }

    public class TestFuc
    {
        //声明更新UI的事件
        public event mydelegate OnUpdateUI;

        public void Test()
        {
            for (int i = 0; i < 10; i++)
            {
                if (OnUpdateUI == null) return;
                OnUpdateUI("ggggggggggggggggg" + ">>>" + i.ToString());
                System.Threading.Thread.Sleep(100);
                OnUpdateUI("hhhhhhhhhhhhhhhh" + ">>>" + (i+1).ToString());
                System.Threading.Thread.Sleep(100);
            }
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值