2013-09-05 130 views
1

我在今天的工作中遇到了一个令我感到困惑的情况,我已经在下面的代码中进行了简化。此代码在调试期间构建并不引发异常。UI线程如何知道另一个线程上的数据?

假设我有一个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; 
     } 
    } 
} 

回答

10

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

线程不是相互之间的沙盒。它们共享资源,除非您明确创建非共享资源。

线程是执行上下文。把你的应用想象成厨房,把每个线程当厨师。他们可以同时工作,但如果其中两人试图同时使用同一把刀,事情会变得混乱。这就是为什么c#有lock关键字和其他同步机制。

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

相关问题