从另一个线程更改主线程'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循环时冻结。
那么我如何从不同的线程更改按钮文本?
你不能从其他线程访问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;
}