C# 1. 子线程通过UI控件的InvokeBeginInvoke方法更新UI

1. 线程间操作无效: 从不是创建控件“textBox1”的线程访问它
//Form1.cs
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 T2
{
    
    
    public partial class Form1 : Form
    {
    
    
        private uint cnt = 0;
        public Form1()
        {
    
    
            InitializeComponent();
            textBox1.Text = cnt.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
    
    
            cnt++;
            textBox1.Text = cnt.ToString();
        }

        private void Reset_Click(object sender, EventArgs e)
        {
    
    
            cnt = 0;
            textBox1.Text = cnt.ToString();
        }

        public void CallToChildThread()
        {
    
    
            cnt += 10;
            textBox1.Text = cnt.ToString();
        }

        private void F1_Click(object sender, EventArgs e)
        {
    
    
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
        }
    }
}

在这里插入图片描述
按下F1按键,弹出:
“System.InvalidOperationException”类型的未经处理的异常在 System.Windows.Forms.dll 中发生

其他信息: 线程间操作无效: 从不是创建控件“textBox1”的线程访问它。
在这里插入图片描述

2. 通过UI控件的Invoke/BeginInvoke方法更新
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 T2
{
    
    
    public partial class Form1 : Form
    {
    
    
        private uint cnt = 0;
        // 第一步:定义委托类型
        // 将text更新的界面控件的委托类型        
        delegate void SetTextCallback(string text);

        public Form1()
        {
    
    
            InitializeComponent();
            textBox1.Text = cnt.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
    
    
            cnt++;
            textBox1.Text = cnt.ToString();
        }

        private void Reset_Click(object sender, EventArgs e)
        {
    
    
            cnt = 0;
            textBox1.Text = cnt.ToString();
        }

        //第二步:定义线程的主体方法
        private void CallToChildThread()
        {
    
    
            cnt += 10;
            SetText(cnt.ToString());
        }

        //第三步:定义更新UI控件的方法
        /// <summary>
        /// 更新文本框内容的方法
        /// </summary>
        /// <param name="text"></param>
        private void SetText(string text)
        {
    
    
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 
            if (this.textBox1.InvokeRequired)//如果调用控件的线程和创建创建控件的线程不是同一个则为True
            {
    
    
                while (!this.textBox1.IsHandleCreated)
                {
    
    
                    //解决窗体关闭时出现“访问已释放句柄“的异常
                    if (this.textBox1.Disposing || this.textBox1.IsDisposed)
                        return;
                }
                SetTextCallback d = new SetTextCallback(SetText);
                this.textBox1.Invoke(d, new object[] {
    
     text });
            }
            else
            {
    
    
                this.textBox1.Text = text;
            }
        }

        private void F1_Click(object sender, EventArgs e)
        {
    
    
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lljss1980/article/details/119280985