2011-10-18 71 views
2

全部:爲什麼非法跨線程*不被檢測到?

我創建了Windows窗體和按鈕。在另一個線程中,我嘗試更改按鈕的文本,並崩潰;但如果我試圖改變按鈕的顏色,它可靠地成功。我認爲,如果您更改了任何Windows窗體控件屬性,它會崩潰。有人能告訴我發生了什麼事嗎?

這裏是我的代碼,不會對註釋掉線崩潰(但我認爲它應該):

Thread thr = new Thread(() => { 
    //myButton.ForeColor = Color.Purple; // this never causes a crash :=(
    myButton.Text = Color.Purple.ToString(); // this always causes a crash. 
}); // 
thr.Start(); 

任何見解將不勝感激!

邁克爾

回答

6

Control.ForeColor屬性設置器調用Invalidate()方法。這在Windows中是線程安全的。它只是在內部窗口狀態下設置「此窗口需要重新繪製」狀態位。直到後來,當Paint事件運行時,窗口才真正發生。在UI線程上。

Winforms包含明確的代碼來抑制異常。

其他示例正在讀取Text屬性(不寫入)。並記錄,InvokeRequired,BeginInvoke,EndInvoke,Invoke和CreateGraphics。而已。

+0

感謝您的澄清。爲了記錄,微軟的文檔不允許有任何歧義,只是指出:「當您在調試器中運行應用程序時,如果創建控件的線程嘗試調用該控件,那麼調試器將引發InvalidOperationException 」。我希望他們已經提供了一點細節...... –

+0

如果文檔是完美的,那麼不需要像StackOverflow這樣的網站:)它的準確率爲98%。 –

+0

對於學術興趣,您是從煤礦個人經驗中發現的這些例子,還是您自己研究過它們(如果是,如何),還是實際記錄在某處? – tomfanning

0

它可靠地成功

不要得寸進尺太遠。遲早它會崩潰。始終在GUI線程上執行修改。

+0

也許你是對的,但是我真的很驚訝_often_ ForeColor沒有任何錯誤。爲什麼?它不是一個UI修改?不應該在調試期間在主線程中完成嗎? – Marco

+1

@Marco:在安全補丁之後,客戶計算機上的行爲可能會發生變化 - 除非它是_documented_行爲。 – Vlad

0

Documentation說:

它是不安全的調用由比創建的控制不使用Invoke方法的另一個線程控制。

在不首先看的情況下穿過街道是不安全的。你不會總是被汽車撞到,但你的機會相當高。

在調試期間以及在某些情況下在運行時可靠地發生此異常。當您調試使用.NET Framework 2.0版之前的.NET Framework編寫的應用程序時,您可能會看到此異常。強烈建議您在看到它時解決此問題,但可以通過將CheckForIllegalCrossThreadCalls屬性設置爲false來禁用它。

相關問題