簡體   English   中英

實現INotifyCollectionChanged的異步線程安全集合

[英]Asynchronous, Thread-Safe Collection Implementing INotifyCollectionChanged

我正在使用Silverlight 5.0,需要實現IList<T>和IList。 我的收藏集將用於不斷地從其內部收藏集中添加和刪除項目,並且UI將具有綁定到該收藏集的元素。 出於性能原因,我不希望UI在每次更改集合時都呈現,因為,我希望對集合進行“一組”更改,然后引發集合更改事件。 我還希望能夠使用Task.Factory方法做到這一點,以使所有內容保持異步。 有沒有人看到如何實現這一目標的好例子?

線程安全的,可觀察的集合在設計上存在問題。 例如,如果您更改了集合,並且引發了該事件,則在處理該事件的同時,可以在另一個線程上更改該集合。 結果,剛剛被告知添加了項目的處理程序可能已經過時(該項目可能已經消失)。

或者,您是否考慮過在集合發生更改時將不可變集合與事件一起使用? 它本質上是線程安全的,並且如果正確應用它不會遭受上述設計問題的困擾。 它可能不符合您對此應用程序的要求-從問題中很難分辨出來。

我建議的方法是為可能需要更新UI的集合的不同方面提供各種標志。 如果集合中的某些內容發生更改並且未設置特定標志,請對其進行設置並在提供的控件和委托上使用Control.BeginInvoke (使用Interlocked或locks以確保標志test-and-set在線程安全的情況下完成時尚)。 UI更新方法應該在執行更新之前測試並清除相應的標志; 如果執行了任何更新,則該方法應循環並重新測試所有標志,直到完成為止,而無需執行任何更新。

使用這種方法,應該可以避免通過BeginUpdate排隊過多的待處理操作。 可能會有一些多余的更新,但通常不會太多。 在某些情況下,使控件的代碼限制每秒執行的更新次數可能會有所幫助; 如果更新例程將循環多次,請啟動計時器並禁用更新,直到計時器到期。 如果計時器到期並且需要更新,請執行更新並重新啟動計時器;否則,請重新啟動計時器。 如果它到期並且不需要更新,請終止計時器。

試圖使對集合的每個更改都反映在“更新”事件中,這會適得其反。 只需確保對顯示的最后一次更新完全發生在對集合的最后一次更改之后。

暫無
暫無

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

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