我敢肯定,這有一個很好的(或至少體面的)原因。它是什麼?在WinForms中,爲什麼不能從其他線程更新UI控件?
回答
因爲你可以很容易地結束死鎖(以及其他問題)。
例如,您的輔助線程可能會嘗試更新UI控件,但UI控件將等待被釋放的輔助線程鎖定的資源,因此兩個線程都會最終等待對方完成。正如其他人所評論的,這種情況並不是UI代碼所特有的,而是特別常見。
在其他語言如C++,你可以自由嘗試做到這一點(沒有被拋出在WinForms的除外),但您的應用程序可能會凍結,停止應該死鎖發生響應。
順便說一句,你可以很容易地告訴你要更新控制UI線程,只要創建一個委託,然後調用(異步)BeginInvoke方法對控制傳遞給它的委託。例如。
myControl.BeginInvoke(myControl.UpdateFunction);
這是相當於1.0/1.1也不例外,從一個工作線程做C++/MFC PostMessage的
這樣,你就沒有兩件事情要同時更新控件。 (如果CPU在寫入/讀取過程中切換到另一個線程,則可能發生這種情況) 當訪問多個線程之間的共享變量時,需要使用互斥鎖(或其他同步)的原因相同。
編輯:
在其他語言如C++你 免費嘗試做到這一點(沒有 拋出異常,如 的WinForms),但你最終會學習 硬辦法!
稀釋是...我的C/C++和C#,因此之間切換是有點更通用的話,我應該去過,對不起......他是正確的,你可以做在C/C++,但它會回來咬你!
回到調試過程中被拋出,你得到的卻是間歇運行時掛方案。太好了! :) 因此,2.0他們使這種情況下拋出一個異常,非常正確。
的實際原因可能是(亞當海爾州)某種併發/ locky問題。 請注意,正常的.NET api(如TextBox.Text =「Hello」;)會包裝SEND命令(需要立即採取措施),如果在執行更新操作的單獨線程上執行該命令,則會產生問題。使用Invoke/BeginInvoke會使用一個POST來替代這個動作。
有關SEND和POST的更多信息here。
還需要在更新函數中實現同步,這些更新函數對同時被調用敏感。對於UI元素來說,這樣做在應用程序和操作系統級別都會很昂貴,而且絕大多數代碼都是完全冗餘的。
一些API提供了一種方法來更改系統的當前線程所有權,以便您可以暫時(或永久)從其他線程更新系統而無需訴諸線程間通信。
我認爲這是一個很好的問題 - 我認爲需要更好的答案。
當然,唯一的原因是某個框架中有某些東西不是非常安全的。這是.NET或Win32的問題 - 爲什麼沒有推動修復源代碼而不是強制執行對我來說感覺像是一個討厭的解決方法?
任何人都知道真正的潛在問題在哪裏?
我認爲這是一個輝煌的問題 - 我覺得有需要更好的 答案。
當然,唯一的原因是有 是某個地方 是不是很線程安全的東西。
「something」幾乎是System.Windows.Forms中每個控件上的每個單個實例成員。
System.Windows.Forms中許多控件的MSDN文檔(如果不是全部),則說「此類型的任何公共靜態(在Visual Basic中爲Shared)成員都是線程安全的。是線程安全的。「
這意味着實例成員如TextBox.Text {get; set;}
不折返。
使這些實例成員中的每個成員都是線程安全的可能會引入大量應用程序不需要的大量開銷。相反,.Net框架的設計者決定,並且我認爲正確的做法是,應該將同步來自多個線程的表單控件的訪問同步的負擔放在程序員身上。
[編輯]
儘管這個問題只問「爲什麼」這裏是一個鏈接,解釋了一篇「如何」:
如何:使線程安全的調用到Windows窗體控件 MSDN上
嗯我不是很確定,但我認爲當我們有進度控制像等待酒吧,進度條時,我們可以從另一個線程更新他們的值,一切都很好,沒有任何毛病。
- 1. 在android中,爲什麼UI不能從UI線程更新?
- 2. 從後臺線程更新UI控件
- 3. 爲什麼從後臺線程更新時不刷新UI組件?
- 4. 無法從WPF中的其他線程更新UI
- 5. 從C#中的線程更新UI的其他方法
- 6. 從不同線程更新UI中的控件
- 7. 在C#winforms中,UI標籤爲什麼不更新並跟上backgroundworker progresschanged事件?
- 8. 的Android如何更新從其他類(UI線程)(真的嗎?)
- 9. 爲什麼非UI線程能夠修改WinForm和TPL中的UI控件?
- 10. Android:在其他線程中操作UI控件,但是
- 11. 訪問從UI以外的其他線程組合框控件
- 12. 爲什麼我的圖像不能在iOS控件中更新?
- 13. gtkmm:從其他線程更新gui?
- 14. 爲什麼只有Android的UI線程更新UI?
- 15. Winforms UI線程編組Business Objects列表正在從後臺線程更新
- 16. UI不能從其他應用程序的數據更新在WPF
- 17. 從線程更新UI
- 18. Windows窗體從其他線程更新控制
- 19. 性能 - 從計時器線程更新UI而不會阻塞UI線程
- 20. 爲什麼必須始終從UI線程創建/更新UI元素?
- 21. 在其他線程上加載WinForms
- 22. 爲什麼android不讓我在我自己的線程中更新我的UI
- 23. 爲什麼WPF中的UI控件具有線程親和性?
- 24. 從後臺線程結果更新WinForms UI
- 25. 從其他線程處理UI
- 26. 爲什麼單線程模型用於將UI更新爲主線程?
- 27. 如何從其他線程訪問主UI線程中的System.Windows.Threading.Dispatcher?
- 28. 無法從非UI線程更新wpf控件
- 29. C#從NATIVE C線程更新WinForms
- 30. 從WinRT中的線程更新UI
我不知道爲什麼這個答案被接受。這根本不是正確的答案。只要你有多個線程就會發生死鎖。 GUI程序中沒有任何固有的東西可以使它們更有可能發生。而且,即使使用BeginInvoke(),它們也很容易發生。 Brian Ensink的答案是正確的。 – mhenry1384 2010-10-06 19:54:31
-1:等待鎖定的資源不是問題。問題在於競爭條件,在任何代碼中大量存在的設計不適用於多線程環境。您甚至可以通過將[CheckForIllegalCrossThreadCalls](http://msdn.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls(VS.80).aspx)設置爲false來檢查此問題,並觀察死鎖免費的操作,直到有趣的事情發生。 – 2011-01-15 11:59:10