2

由於某些原因,傳統上我在C#中使用BackgroundWorkers遇到了很多麻煩;他們的概念似乎真的難倒我,所以我希望這是一個相當基本的問題,東西可以很容易地矯正足...C# - BackgroundWorker不斷更新控件:錯誤!

我有使用.NET Remoting來來回溝通兩種形式。現在,更改Form1上的設置會導致Form2上的某些內容發生更改,這非常有用。然而,現在我需要讓相同的事情以另一種方式工作(更改Form2上的某些內容會導致Form1更新),而且我無法以相同的方式執行此操作(由於設計中的限制,我無法將其更改爲由Form2發送更改到Form1)。現在,我試圖在Form1上使用BackgroundWorker來不斷調用每個子控件(放置在Form1上)上的Update()方法。這些控件中的每一個都有辦法從Form2中獲取它們的等效設置的當前狀態並更新它們自己(這很有效;'Update()'方法已經被用於Form1的初始化)。

這裏就是我的問題來了。我不確定BackgroundWorker如何在每個表單上不斷地調用Update(),所以在我的'DoWork()'方法中,我有一個「while(true)」循環,並且在這個循環內,BackgroundWorker調用'Update ()'的方法,然後睡了很短的時間,然後重複。

這樣做,我得到一個「InvalidOperationException未被用戶代碼處理」的錯誤,詳細信息指出「跨線程操作無效:控制'comboBox_BGColor'從其創建的線程以外的線程訪問。 「現在,我基本知道這意味着什麼,並且我明白爲什麼會發生這種情況,但是,我不確定要做什麼不同,或者如何改變事情以使其按預期工作。任何人有任何提示或我使用BackgroundWorker的方式?非常感謝任何信息,並花時間閱讀本文!

回答

3

UI控件有線程關聯。您不應該從UI線程以外的任何線程觸摸控件(用於讀取寫入)。如果BackgroundWorker正在向用戶界面說主要是,那麼只需控制Timer即可,這樣可以避免需要多次調用InvokeBeginInvoke

然而,一般我寧願更多的「觀察員」爲基礎的設計在這裏,與更改通知事件(無論是FooChangedINotifyPropertyChanged)和事件處理程序導致UI來反映變化。

1

你需要定時器控制,而不是後臺工作

1

您收到將打電話Update()的結果直接從_DoWork(這是修改你的主線程中的一個或多個形式)您的BackgroundWorker的線程中的異常。

如果你打算使用BackgroundWorker方法:

  • 設置你的工人.WorkerReportsProgress屬性true
  • 當你執行你的循環,使用工作的.ReportProgress()方法引發工人的_ProgressChanged事件處理程序。
  • _ProgressChanged事件處理程序就可以進行撥打您的窗體的Update()方法安全

如果您使用的工人(特別是如果你的後臺工作僅僅存在這種循環)搬開,然後我建議你使用標準事件處理程序的Marc's suggestion。該路線將產生較少的處理器開銷(但目前可能或不可能達到最低限度),而不是增加外部循環或Timer控制器。

任一路徑都應該解決跨線程異常。