c# - UI线程如何知道另一个线程上的数据?

标签 c# multithreading winforms

我遇到了一种情况,使今天的工作感到困惑,在下面的代码中我对此进行了简化。该代码在调试过程中会生成并且不会引发任何异常。

假设我有一个WinForms应用程序。在我的主UI线程中,我产生了另一个线程,该线程实例化了一个对象,该对象又持有对控件的引用(在我的示例中为label1)。然后,我在对象(SetLabelText)上调用一个方法,如果需要,该方法将其执行返回给UI线程。

让我感到困扰的是,当我们在未创建Thing实例的线程(即UI线程)上执行时,当我们回到UI线程并执行SetLabelText时,.net CLR能够访问labelText变量。

public partial class Form1 : Form
{
    delegate void DoSomethingDelegate();

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var t = new Thread(DoSomethingWithThing);
        t.Start();
    }

    private void DoSomethingWithThing()
    {
        var thing = new Thing(this.label1);
        thing.SetLabelText();
    }
}

public class Thing
{
    private Label label;
    private string labelText = "new value";
    delegate void SetLabelTextDelegate();

    public Thing(Label label)
    {
        this.label = label;
    }

    public void SetLabelText()
    {
        if (this.label.InvokeRequired)
        {
            var setLabelDel = new SetLabelTextDelegate(SetLabelText);
            this.label.Invoke(setLabelDel);
        }
        else
        {
            this.label.Text = this.labelText;
        }
    }
}

最佳答案

对对象的引用在任何线程上都可用。

线程彼此之间没有沙盒。它们共享资源,除非您显式创建非共享资源。

线程是执行上下文。将您的应用程序视为厨房,将每个线程视为厨师。它们可以同时工作,但是如果其中两个试图同时使用同一把刀,事情就会变得困惑。这就是为什么C#具有lock关键字和其他同步机制的原因。

由于WinForms呈现的方式,WinForms对控件的访问有限制。

关于c# - UI线程如何知道另一个线程上的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18640031/

相关文章:

c# - IBM MQ 客户端向后兼容性

c# - 在后面的代码中多次绑定(bind)到 TextBlock - 我在哪里弄错了?

c# - 如何使 TextBox 使用密码字符而不是在 wpf 中使用密码框?

multithreading - 在多线程中解析时,输入字符串的格式不正确

c# - 使用mysql插入数据时出现语法错误

c# - C 到 C# PInvoke 带指针的结构

Python线程/守护进程

c# - Task.Delay 在专用线程上有意义吗?

c# - 将光标保持在数据 GridView 的特定列内

c# - XmlSerializer,生成 XML 文档时出错