Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从正在运行的线程C更改窗体上的属性_C#_Multithreading_Variables - Fatal编程技术网

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

C# 从正在运行的线程C更改窗体上的属性,c#,multithreading,variables,C#,Multithreading,Variables,我发现运行线程在很大程度上与主应用程序是隔离的。您不能更改在类中全局声明的变量,也不能通过在线程中简单地给它们新值来更改表单属性或任何东西 当线程运行时,如何从线程内部更改标签中的文本 我认为没有必要锁定该值,因为它没有在主程序中使用,所以不会发生死锁 我所尝试的,都失败了 具有全局变量int=0 运行测试线程以将变量更改为5 当我想在我的线程messagebox.showint.tostring之外显示该数字时,var仍然是0 你将如何从一个线程中改变主窗体中/上的内容 代码 创建我没有使用的

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

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

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

我所尝试的,都失败了

具有全局变量int=0

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

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

你将如何从一个线程中改变主窗体中/上的内容

代码

创建我没有使用的线程的代码如下所示

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

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

当我试图编辑或更改线程上的内容时

所以我用了这个代码

lbldirectory是我的分部类的名称

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

如果需要从后台线程访问GUI,则需要使用以下方法:


如果您在多个线程之间共享了一些变量,那么每次其中一个线程访问共享变量时,必须使用其中一种同步技术进行显式保护。我想您可以在这里找到大量必要的信息:

如果需要从后台线程访问GUI,则需要使用以下方法:


如果您在多个线程之间共享了一些变量,那么每次其中一个线程访问共享变量时,必须使用其中一种同步技术进行显式保护。我想你可以在这里找到大量必要的信息:

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

1.更改GUI控件:只有GUI线程应更改控件。其他线程需要通过Invoke/BeginInvoke将其更新转发到GUI线程,例如:


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

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

1.更改GUI控件:只有GUI线程应更改控件。其他线程需要通过Invoke/BeginInvoke将其更新转发到GUI线程,例如:


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

请显示代码。这里有些东西不对劲。线程共享包含进程的地址空间,因此它们应该能够更改int变量。改变控件是一个不同的故事。你最好展示一下DoWorkIve的代码。我添加了一个简单的例子,它也不起作用。这只是为了理解背后的原理,以及为什么它在线程中不起作用。@Ruan您应该使用窗体或按钮的Invoke方法。这正是我所期望的。请参阅我的答案以了解Invoke/BeginInvoke解释。请显示代码。这里有些东西不对劲。线程共享包含进程的地址空间,因此它们应该能够更改int变量。改变控件是一个不同的故事。你最好展示一下DoWorkIve的代码。我添加了一个简单的例子,它也不起作用。这只是为了理解背后的原理,以及为什么它在线程中不起作用。@Ruan您应该使用窗体或按钮的Invoke方法。这正是我所期望的。有关调用/开始调用的解释,请参见我的答案。这也是一个很好的C线程指南。同步所需的一切都包括在内。谢谢你的回答,如果我能把2作为正确的答案,我会的!!再次感谢你,你真的帮助了我!这也是一个很好的C线程指南。同步所需的一切都包括在内。谢谢你的回答,如果我能把2作为正确的答案,我会的!!再次感谢你,你真的帮助了我!谢谢你,现在明白你的意思了。现在一切都在运转,学到了一些东西。谢谢你,现在明白你的意思了。现在一切都在运转,并且学到了一些东西。
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);
                }
            }
public void DoWork()
{
    button1.Invoke(new Action(() =>
    {
        button1.Text = "Hello there";
    }));            
}
 var t = new Thread(
    o => 
    {
         textBox.BeginInvoke(
             ((Action)(() => textBox.Text = "text")));
    });