软件编程
位置:首页>> 软件编程>> C#编程>> C# 多线程更新界面的错误的解决方法

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

作者:caimouse  发布时间:2022-01-20 15:52:21 

标签:C#,多线程,更新界面

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

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

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

在上面的例子里,创建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.";
   }
}

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

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

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

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


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;
       }
   }
}

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

来源:https://www.tuicool.com/articles/Q3emiyz

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com