从另一个线程更改主线程's按钮文本

本文关键字:线程 按钮 文本 另一个 | 更新日期: 2023-09-27 18:07:43

我有一个名为Form1的类,其中有一个按钮。现在,在那个类中,我创建了另一个线程。

如果我试图从新线程以任何方式改变按钮,我得到跨线程错误/异常

new Thread(delegate ()
            {
                while (!DL.HasExited)
                {
                    Thread.Sleep(500);
                }
                File.Delete(folderBrowserDialog1.SelectedPath + @"'Steam'steamcmd.zip");
            //The code below this note is the problem
                button1.Text = "START DOWNLOADING";
                button1.Enabled = true;
            }).Start();

我需要在新线程中有代码,因为我不想让我的程序在到达while循环时冻结。

那么我如何从不同的线程更改按钮文本?

从另一个线程更改主线程's按钮文本

你不能从其他线程访问UI元素属性。使用beginInvoke

button1.BeginInvoke( new MethodInvoker(() =>
{
      button1.Text = "START DOWNLOADING";
      button1.Enabled = true;
}));

使用Invoke()。这个函数接受委托(你也可以传递一个匿名函数)。比如:

Invoke(() => {
    button1.Text = "START DOWNLOADING";
    button1.Enabled = true;});

线程不应该扰乱彼此的内存空间-因此,您尝试简单地更改文本将失败。但是,我可以想到3种解决方案:

  • Using invoke()

正如其他人在我之前几秒钟提到的,您可以使用invoke以另一种形式更改文本。但是,如果您希望线程之间有更多的通信,那么这将是低效的。

  • 使用共享资源

为了在线程之间进行会话,您可以使用将用于它们通信的公共资源。这方面的一个非常基本的例子是,将您希望按钮显示的文本从线程写入文本文件,并每隔几秒钟从其他线程读取并检查更改。有一些更好的方法,这只是一个例子。如果你想让我给你看一个这种方法的例子,问我,我很乐意提供它。

  • 使用进程代替线程

进程和线程都允许您需要的多任务,但是,进程之间可能会相互干扰。在做决定之前,你应该阅读更多的差异,这就留给你了——你认为哪个更适合这些,一个过程还是一个线程?如果您愿意的话,我也很乐意提供一个使用过程的示例。

祝你好运

最简单的方法是在控件上使用BeginInvoke函数:

public delegate void InvokeDelegate();
new Thread(delegate ()
{
    while (!DL.HasExited)
    {
        Thread.Sleep(500);
    }
    File.Delete(folderBrowserDialog1.SelectedPath + @"'Steam'steamcmd.zip");
    //The code below this note is the problem
    button1.BeginInvoke(new InvokeDelegate(InvokeMethod));
}).Start();
public void InvokeMethod()
{
   button1.Text = "START DOWNLOADING";
   button1.Enabled = true;
}