2013-08-27 22 views
4

在MvvmCross解決方案中,我有一個單例服務類,它從Web服務獲取項目並更新公共ObservableCollection。它每五秒鐘執行一次,可能會添加或刪除項目或更改其屬性。關於MvvmCross中ObservableCollection何時何地使用的建議

我也有一個ViewModel有一個公共屬性設置爲服務的ObservableCollection。視圖綁定到ObservableCollection,以便在添加,刪除或更改項目時,視圖應該更新以顯示此內容。

但是,正如預期的那樣,我得到一個線程異常,因爲ObservableCollection正在被主/ UI以外的線程更新,因此綁定無法更新UI。

在服務內我沒有InvokeOnMainThread調用可用,所以在更新ObservableCollection時,沒有明顯的跨平臺方式來回到主線程。另外,這樣做似乎是錯誤的 - 服務不應該關注UI問題(而ViewModel可以)。

另外我對暴露服務中的事件感到有點緊張,以防這導致ViewModels不被垃圾收集。我注意到,在@ slodge的N + 1系列http://mvvmcross.wordpress.com/中,他正在使用一種消息傳遞服務,以避免這種情況。

所以一個可能的解決方案可能是發佈消息與最新的項目列表,並使ViewModel訂閱消息並通過比較消息內容與UI線程更新自己的ObservableCollection。但這似乎有點笨重。

任何建議,以實現這一點的最佳方式將不勝感激 - 謝謝。

回答

12

必須在UI線程上調用INotifyCollectionChanged的原始要求確實來自Windows控件基於添加/移除/移動/替換/重置通知進行更新的同步方式。

這個同步更新當然是完全合理的 - 當另一個線程正在主動更改它時,更新UI顯示將非常困難。

有「新」變化.NET 4.5,這可能意味着未來更好......但總體而言這些看起來相當複雜,我 - 看https://stackoverflow.com/a/14602121/373321


我知道的方式來處理這個與您的文章中列出的內容基本相同:

A.將ObservableCollection保留在服務/模型層中,並將所有事件封送到UI線程 - 這可以使用任何繼承自MvxMainThreadDispatchingObject的類 - 或者可以是致電MvxMainThreadDispatcher.Instance.RequestMainThreadAction(action)

雖然不幸的是,這意味着您的服務/模型確實具備一些線程知識,但這種方法對於整體應用程序體驗來說可以很好地工作。

B.使收集的副本在ViewModel - 一些弱引用類型的機制

  • 例如更新它通過發送消息告訴它已添加,刪除,替換或移動(或完全重置) - 請注意,爲使其正常工作,請務必按照正確的順序到達消息!

  • 或例如被對面的服務/模型層允許發送快照

在以下這些選擇取決於:

  • 的集合的頻率發生變化,類型和大小 - 例如是否只是偶爾進行單行更新,是否正在頻繁發生大量突發變化,或者您是否主要看到複雜的變化組(根據UI而言基本上爲Resets
  • 需要動畫級別在用戶界面 - 例如應添加/刪除項目動畫進/出?如果不需要動畫,那麼只需用新的快照替換整個列表就可以了,而不是計算增量更改。
  • 集合本身的規模 - 顯然複製收集了大量可能導致了內存不足的問題
  • 在收集所需的持久性 - 如果需要持久性,那麼ObservableCollection本身可能不適合,你可能需要使用自定義INotifyCollectionChanged地執行(如the MyCustomList samples

我個人一般選擇在應用程序中(A)的做法 - 但它取決於形勢以及收集及其變化的特點。

請注意,雖然這絕對是mvvm問題,但底層問題是獨立於數據綁定的問題 - 當列表本身在後臺線程中更改時,如何更新列表的屏幕顯示?

+0

新的'EnableCollectionSynchronization'看起來有趣,但你是對的 - 它看起來很複雜,不得不實現鎖定與編組事件一樣麻煩。好吧,看起來像A IS畢竟是可行的,我猜如果ViewModel沒有處理它的任何事件,那麼它將不會通過服務引用而保持活動。所以,再次感謝全面的回答以及如何從服務返回主線程的提示。 –

+0

我試過這個'MvxMainThreadDispatcher.Instance.RequestMainThreadAction',但它沒有幫助:(還有什麼可以做的? – DanilGholtsman

+0

https://stackoverflow.com/questions/47728293/on-android-device-ui-update-happens - 僅在用戶交互後的完整問題 – DanilGholtsman