2013-09-05 92 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對訪問控件有限制。

相關問題