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

时间:2013-09-05 15:12:44

标签: c# multithreading winforms

我遇到了一个困扰我今天工作的情况,我在下面的代码中进行了简化。此代码在调试期间构建并抛出无异常。

假设我有一个WinForms应用程序。在我的主UI线程中,我关闭另一个实例化对象的线程,该对象又控制对象的控制(在我的例子中为label1)。然后我在我的对象(SetLabelText)上调用一个方法,如果需要,它会将它的执行传递回UI线程。

让我感到困惑的是,当我们回到UI线程并执行SetLabelText时,当我们在没有创建实例的线程(即UI线程)上执行时,.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;
        }
    }
}

1 个答案:

答案 0 :(得分:10)

任何线程都可以参考对象。

线程彼此没有沙盒。除非您明确创建非共享资源,否则它们共享资源。

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

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