簡體   English   中英

非UI對象上的跨線程事件處理

[英]Cross-thread event handling on non-UI object

我在處理與引發事件的線程不同的事件上遇到問題。 但是,處理事件的對象不是UI對象,因此無法使用Invoke執行委托並自動切換到UI線程進行事件處理。

情況如下:我有一個包含多個表單的MDI應用程序。 每個表單都有其自己的控制器類,該類處理耦合的表單和外部對象之間的通信。 所有表單都是概述表單或明細表單(例如ContactsOverview和ContactDetail),並且共享相同的數據。

在發生錯誤的情況下,表單以類似向導的順序出現,例如,詳細表單之后是概述表單。 在明細表中,更改了以下總覽表上使用的數據,並且在切換到總覽表之前,這些更改需要在此反映出來。 從詳細信息表單引發一個事件,並由控制器處理該概述表單,該表單對UI元素進行必要的更新。

現在,將更改后的數據保存在詳細信息表單中可能需要一段時間,因此有必要使UI保持響應狀態,並且仍然可以使用應用程序的其他部分。 這就是為什么背景工作人員開始處理此問題的原因。 保存數據后,將在后台線程上引發事件。 概述的控制器可以處理此問題,但是當需要更新UI時,當然會有跨線程異常。

所以我需要一種在UI線程上引發事件的方法,但是由於UI元素上沒有進行處理,因此無法使用Invoke自動切換線程。

通過在網上搜索,我發現了一種可能的解決方案,即使用生產者/消費者模式。 但是據我所知,這將要求每個控制器在單獨的線程中偵聽事件隊列。 由於它是MDI應用程序,因此從理論上講控制器可以有任意多種形式,而我不想啟動那么多線程。

歡迎任何建議。 如果有一種方法可以避免一起使用背景工作人員,那也是一個合適的解決方案。

謝謝閱讀,

凱文

您可以使用SynchronizationContext ,特別是SynchronizationContext.Current ,將消息發布到主同步上下文(這是GUI應用程序的主線程)。

不幸的是,我對該類及其用法不了解,無法肯定地說這是一個解決方案。 特別是,我不知道如果不需要主線程來處理事件,而是需要特定線程來處理,該怎么辦。

也許WindowsFormsSynchronizationContext類可以為您提供幫助,它具有一個公共的無參數構造函數,我認為它可能將其與當前線程相關聯,因此,如果您從擁有控制器的線程中構造該對象,並將其提供給后台線程代碼,它可能會起作用。

您可以在UI元素訂閱的背景objec上有一個事件。 然后,在(訂閱的事件處理程序中-它是窗口代碼的一部分)您可以進行調用。 這就是我解決這個問題的方式。

您可以嘗試使用此標志,但我認為這不是最好的主意,只是解決方法。

您也可以嘗試在非圖形線程中實例化發行對象,這可能會解決您的問題。

還有一件事,您是否不能讓UI組件處理RunWorkerCompleted(帶有間接調用)?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM