[英]Is it possible to access a UI element from another thread if the thread doesn't modify that element?
假設在實例化表單/ control / element(通常是主線程)的線程中運行的代碼不會同時修改/訪問該元素,是否可以:
獲取TextBox的Text屬性。
枚舉ListView。
訂閱Form的Closing事件。 (知道將從實例化該表單的線程調用鈎子)
我已經嘗試了所有3並且程序似乎沒有抱怨它。 我一直認為你必須調用任何想要遠程觸摸任何UI相關(讀或寫)的調用。
我非常清楚為什么在修改元素時需要使用IsInvokeRequired / Invoke模式,但我不明白為什么訪問屬性/事件會導致任何問題。
但這絕對有可能導致意外行為。 此外,還需要考慮其他與線程相關的錯誤,例如競爭條件/死鎖,請參閱托管線程最佳實踐 。
我總是堅持訪問UI線程上的UI以保證安全。
你正在做什么來確保UI線程在你讀取它時沒有修改控件? 編組到UI線程的全部原因是您不必擔心這種情況。 特別是枚舉列表框將是最容易打破的,因為它將花費最長的時間(這為競爭條件創建了最大的窗口)。 你應該為所有這3個事情的UI線程編組。
這不安全。 當您從另一個線程讀取控件時,UI線程可以(也可能會)更改控件的狀態。 您的讀取可能會在半生不熟的狀態下捕獲控件。 它似乎現在可以正常工作,但遲早它會失敗......可能是不可預測的和驚人的。
不,您可能不需要使用Invoke模式。 坦率地說......這種模式通常是最糟糕的選擇。 通常最好讓您的工作線程執行繁重的工作,然后通過隊列將新數據或進度信息發送到UI線程,並讓UI線程通過計時器選擇它。 這有幾個優點。
Invoke
和BeginInvoke
操作。 Invoke
返回。 BeginInvoke
一樣,不存在超出UI消息隊列的風險。 您需要枚舉ListView
並構建一個單獨的數據結構,然后工作線程可以安全地訪問它。 如果ListView
包含許多項目,請考慮與控件一起維護單獨的集合。 這樣你就可以在更長的時間內分散處理數據的懲罰,因為它可能不會被注意到。 畢竟,我們不希望復制操作凍結UI線程,否則用戶會注意到。 ConcurrentBag
等可能是一個不錯的選擇,因為當工作線程正在讀取它時,UI線程可以安全地修改它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.