1

我发现运行线程在很大程度上与主应用程序隔离。您不能更改变量(在您的类中全局声明),也不能通过简单地在线程中给它们新值来更改表单属性或任何东西。

当线程运行时,您将如何从线程内部更改标签中的文本?

我不认为锁定值是必要的,因为它没有在主程序中使用,所以不会发生死锁。

我尝试了什么,失败了。

有一个全局变量(int = 0)

运行测试线程将变量更改为 5。

当我想在我的线程(messagebox.show(int.tostring())之外显示该数字时,var仍然是0

您将如何从线程中更改主窗体中/主窗体上的内容?

代码

创建一个我没有使用的线程的代码就是这个。

        Thread threadA = new Thread(new ThreadStart(DoWork));
        threadA.Start();

当我使用这种方式时,我得到了错误

“跨线程操作无效:控件'button1'从创建它的线程以外的线程访问”

当我尝试在我的线程上编辑或更改某些内容时。

所以我使用了这段代码。

lbldirectory 是我的部分类的名称。

            // StartFileCheckProcess();
            workerObject = new lbldirectory(); 
            workerThread = new Thread(workerObject.DoWork);

            // the worker thread.
            workerThread.Start();

DoWork 是我的课程,我尝试更改表单上的属性。

这是 DoWork 类。它确实是一个简单的类,但它只是为了了解为什么会发生这种情况,而其他人只是为了了解他们为什么以及如何克服这一点。

public void DoWork()
        {
            button1.Text = "Hello there";
        }

这样运行线程,线程工作,它只是不能改变我表单上的任何东西。

修改后的答案(由 Tudor 和 Konstantin Vasilcov 提供)

在按钮单击事件上。

var t = new Thread(TEST);
    t.Start();

线程启动的类

private void TEST()
            {
                for (int i = 0; i < 10; i++)
                {
                    lbl_CurrentFile.BeginInvoke(
                    ((Action)(() => lbl_CurrentFile.Text = i.ToString())));
                    Thread.Sleep(1000);
                }
            }

这成功地更改了线程内标签的文本

4

2 回答 2

7

好的,这里有两件事要注意:

1.更改GUI控件:只有GUI线程才能对控件进行更改。其他线程需要通过Invoke/将它们的更新转发到 GUI 线程,BeginInvoke例如:

 var t = new Thread(
    o => 
    {
         textBox.BeginInvoke(
             ((Action)(() => textBox.Text = "text")));
    });

2.更改标量值或引用:这通常可以毫无问题地完成,但要小心数据竞争。

于 2012-10-03T07:35:56.307 回答
6

如果需要从后台线程访问 GUI,则需要使用Control.Invoke方法:

public void DoWork()
{
    button1.Invoke(new Action(() =>
    {
        button1.Text = "Hello there";
    }));            
}

如果您在多个线程之间共享一些变量,则每次由其中一个线程访问共享变量时,都必须受到其中一种同步技术的显式保护。我想你可以在那里找到大量必要的信息:Thread Synchronization (C# Programming Guide)

于 2012-10-03T07:33:23.083 回答