从正在运行的线程C#更改窗体上的属性

Rua*_*uan 1 c# variables multithreading

我发现运行一个线程在很大程度上与主应用程序隔离开来.您无法更改变量(在您的类中全局声明),并且您无法通过在线程中为它们提供新值来更改表单属性或任何内容.

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

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

我尝试了什么,失败了.

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

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

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

你会如何在一个主题中更改主表单中的内容?

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

        Thread threadA = new Thread(new ThreadStart(DoWork));
        threadA.Start();
Run Code Online (Sandbox Code Playgroud)

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

"跨线程操作无效:控制'button1'从其创建的线程以外的线程访问"

当我尝试编辑或更改我的线程上的东西时.

所以我使用了这段代码.

lbldirectory是我的部分类的名称.

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

            // the worker thread.
            workerThread.Start();
Run Code Online (Sandbox Code Playgroud)

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

这是DoWork类.它真的是一个简单的类,但它只是为了理解为什么会发生这种情况,而对于其他人来说只是为了理解为什么以及如何克服这个问题.

public void DoWork()
        {
            button1.Text = "Hello there";
        }
Run Code Online (Sandbox Code Playgroud)

所以运行线程,线程工作,它只是不能改变我的表单上的任何东西.

修改后的答案(由都铎和康斯坦丁·瓦西尔科夫提出)

在按钮单击事件上.

var t = new Thread(TEST);
    t.Start();
Run Code Online (Sandbox Code Playgroud)

线程启动的类

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

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

Tud*_*dor 7

好的,这里有两件事要记住:

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

 var t = new Thread(
    o => 
    {
         textBox.BeginInvoke(
             ((Action)(() => textBox.Text = "text")));
    });
Run Code Online (Sandbox Code Playgroud)

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


hor*_*rgh 6

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

public void DoWork()
{
    button1.Invoke(new Action(() =>
    {
        button1.Text = "Hello there";
    }));            
}
Run Code Online (Sandbox Code Playgroud)

如果您在多个线程之间共享一些变量,则每次其中一个线程访问共享变量时,必须明确地使用其中一个同步技术进行保护.我想你可以在那里找到大量必要的信息:线程同步(C#编程指南)