我知道在Windows應用程序後臺線程不允許直接訪問GUI項目。我不完全明白的是爲什麼。我發現的最接近的解釋是:爲什麼不能從後臺線程訪問Windows GUI?
訪問Windows窗體控件本質上不是線程安全的。如果您有兩個或更多個線程操縱控件的狀態,則可以強制控件進入不一致狀態。其他線程相關的錯誤是可能的,例如競態條件和死鎖。確保以線程安全的方式訪問您的控件非常重要。
任何人都可以詳細說明兩個線程可以做什麼的具體示例,將窗口項放入不一致的狀態嗎?
我知道在Windows應用程序後臺線程不允許直接訪問GUI項目。我不完全明白的是爲什麼。我發現的最接近的解釋是:爲什麼不能從後臺線程訪問Windows GUI?
訪問Windows窗體控件本質上不是線程安全的。如果您有兩個或更多個線程操縱控件的狀態,則可以強制控件進入不一致狀態。其他線程相關的錯誤是可能的,例如競態條件和死鎖。確保以線程安全的方式訪問您的控件非常重要。
任何人都可以詳細說明兩個線程可以做什麼的具體示例,將窗口項放入不一致的狀態嗎?
Winforms和WPF不是線程安全的,因爲Windows窗口不是線程安全的。一般來說,有大量狀態的大量代碼從來不是線程安全的,但這樣做太難了。它不限於user32和gdi32,例如瀏覽器不是線程安全的。即使微軟爲了使窗口線程安全而經歷了非常長的時間,它在實踐中仍然不能很好地工作。因爲這不會自動使您的代碼線程安全。如果線程不協調以確定窗口應該是什麼樣子的話,那麼你仍然會對抗毛刺。一個很難解決的問題,我有傷痕來證明它。通用的解決方案是隻讓一個線程負責其內容。
在Windows中,只有kernel32是線程安全的。必然如此,如果情況並非如此,你將無法安全地使用線程。你可以在kernel32 api函數中看到它,它們做的事情非常小,影響很小的狀態。
其實,Windows是線程安全的。 (例如,您可以從任何線程調用GetWindowText)。問題是編寫使用Windows的代碼的人很少編寫線程安全的代碼。線程安全性很難。您從一個線程更新值,但由於緩存一致性問題,該值直到一段時間後纔會變爲對其他線程可見。或者您從一個線程讀取值,並且在您仍在使用該值時,另一個線程使其無效。這些錯誤會讓人們瘋狂。標準的解決方案是說:「不要那樣做,別嘗試,你會發瘋的。」 –
無論是通過API直接使用還是私下在API中共享狀態(如結構)都可能很容易被搞亂。其具體內容可能因操作系統版本而異。如果有人說他們的代碼不是線程安全的,我就不會冒着代碼冒險,因此總是練習安全線程。 :) – WiredPrairie