2013-11-24 16 views
2

看來,C#有時會爲跨線程操作拋出異常。例如,您可以嘗試在Windows窗體程序中運行此示例代碼:當我允許跨線程訪問和什麼時候我不是?

public Form1() 
    { 
     InitializeComponent(); 
     Thread setTextT = new Thread(TextSetter); 
     setTextT.Start(); 
    } 

    private void TextSetter() 
    { 
     //Thread.Sleep(4000); 
     textBox1.Text = "Hello World"; 
    } 

它不會拋出任何異常,一切似乎都正常工作。現在,當您取消註釋Thread.Sleep行時,它會爲嘗試的跨線程訪問引發異常。

爲什麼會出現這種情況?

+0

有時,它不會對你吹起來。雖然你不應該這樣做。 –

回答

5

這是因爲跨線程檢查只發生在the window's handle已創建後,因爲您正在檢查的是跨窗口句柄的線程訪問。當你沒有睡眠時,代碼在第一次顯示控件之前運行得足夠快(首次顯示控件時就會創建控件)。

的easyist辦法知道,如果你需要小心的UI控件的跨線程訪問時只檢查InvokeRequired,如果這是真的,你需要調用Invoke(或BeginInvoke如果你不想等待它完成)來創建控件的線程。

+3

這就是爲什麼你應該在窗體的Load事件中啓動線程,而不是從構造函數中啓動線程。這樣,你會得到更一致的行爲。 – Baldrick

+0

@Baldrick好點。 @Andrew Load事件發生在表單加載和顯示之後,這樣你現在知道你不需要擔心在你的方法中創建的控件。 –

0

試試這個:

public Form1() 
    { 
     InitializeComponent(); 
     Thread setTextT = new Thread(TextSetter); 
     setTextT.Start(); 
    } 

    private void TextSetter() 
    { 
     //Thread.Sleep(4000); 
     //textBox1.Text = "Hello World"; 
     //You have to Invoke your action to the UI thread 
     Invoke(new Action(()=>textBox1.Text = "Hello World")); 
    } 
相關問題