信息发布→ 登录 注册 退出

C# 多线程更新界面的错误的解决方法

发布时间:2026-01-11

点击量:
目录

    由于一个线程的程序,如果调用一个功能是阻塞的,那么就会影响到界面的更新,导致使用人员操作不便。所以往往会引入双线程的工作的方式,主线程负责更新界面和调度,而次线程负责做一些阻塞的工作。

    这样做了之后,又会导致一个常见的问题,就是很多开发人员会在次线程里去更新界面的内容。比如下面的例子:

    在上面的例子里,创建Win forms应用,然后增加下面的代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                var thread2 = new System.Threading.Thread(WriteTextUnsafe);
                thread2.Start();
            }
    
            private void WriteTextUnsafe() =>
                textBox1.Text = "This text was set unsafely.";
        }
    }
    

    这里就是使用线程来直接更新界面的内容,就会导致下面的出错:

    这样在调试的界面就会弹出异常,但是有一些开发人员不是去解决这个问题,而是去关闭开发工具的选项,不让弹出这个界面。或者不使用调试方式。

    其实上面的代码是有问题的,我们需要把它们修改为下面这种形式:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                var threadParameters = new System.Threading.ThreadStart(
                    delegate { WriteTextSafe("This text was set safely."); });
                var thread2 = new System.Threading.Thread(threadParameters);
                thread2.Start();
            }
    
            public void WriteTextSafe(string text)
            {
                if (textBox1.InvokeRequired)
                {
                    // Call this same method but append THREAD2 to the text
                    Action safeWrite = delegate { WriteTextSafe($"{text} (THREAD2)"); };
                    textBox1.Invoke(safeWrite);
                }
                else
                    textBox1.Text = text;
            }
        }
    }
    
    

    这样问题,就得了解决。这里使用了委托的方式。

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!