我正在使用Silverlight 5.0並需要實現IList<T>
和IList。我的集合將用於不斷添加和刪除其內部集合中的項目,並且UI將具有綁定到集合的元素。出於性能方面的原因,我不希望UI在每次更改集合時都進行渲染,因爲我希望對集合進行「組」更改,然後引發集合更改事件。我也希望能夠使用Task.Factory方法來完成這一切,以保持一切異步。有沒有人看到如何實現這一目標的好例子?異步,線程安全的集合實現INotifyCollectionChanged
回答
線程安全的可觀察集合在設計上存在問題。例如,如果更改集合並引發事件,則在處理該事件時,可以在另一個線程上更改集合。結果,剛剛被告知某個物品的處理程序已經過期(該物品可能已經不存在了)。
或者,您是否考慮在集合更改時使用帶有事件的immutable collection?它本質上是線程安全的,如果正確應用它,不會受到上述設計問題的困擾。它可能不符合你對這個應用程序的要求 - 從這個問題很難說。
處理程序可能在過期後調用的事實不應被視爲問題。處理程序處理這些事情並不困難,並且沒有理由不應該爲他們準備一個體面的處理程序。更大的問題是當事件處理程序已經運行時,可能會將某些內容添加到集合中。通常,調用SomeCollection.Add的代碼有權假定所有事件處理程序在返回之前都會觸發,但強加此類語義會造成死鎖的可能性。 – supercat 2012-12-31 20:00:52
我建議的方法是爲可能需要更新UI的集合的不同方面設置各種標誌。如果集合中的某些內容發生更改並且未設置特定的標誌,請設置它並在提供的控件和委託上使用Control.BeginInvoke
(使用Interlocked
或鎖定以確保標誌測試和設置是以線程安全的方式完成的) 。 UI更新方法應該在執行更新之前測試並清除相應的標誌;如果執行了任何更新,該方法應循環並重新測試所有標誌,直到完成而不必執行任何更新。
使用這種方法,應該能夠避免通過BeginUpdate
排隊的過多數量的掛起操作。可能會有一些重複的更新,但通常不會太多。在某些情況下,讓控件的代碼限制每秒執行的更新次數可能會有所幫助;如果更新例程將循環太多次,則啓動一個定時器並禁用更新,直到定時器到期。如果定時器到期並需要更新,請執行更新並重新啓動定時器;如果過期並且不需要更新,則取消定時器。
試圖對集合進行每一次更改都會反映在「更新」事件中,這樣做容易起反作用。只要確保顯示的最後一次更新完全發生在集合的最後一次更改之後。
- 1. 鏈接線程安全集合線程安全嗎?
- 2. 異步文件IO線程安全嗎?
- 3. 線程安全異步字節隊列
- 4. 線程安全的找到並集合
- 5. .NET中的線程安全集合
- 6. 線程安全VS異步信號安全
- 7. .NET 2.0:File.AppendAllText(...) - 線程安全的實現
- 8. 實現'線程安全的'鏈表
- 9. 成員集合迭代線程安全
- 10. IStorage的複合文件實現是線程安全的嗎?
- 11. 存儲在線程安全集合線程中的對象是否安全?
- 12. 線程安全日誌類實現
- 13. 是LinkedList實現.Net線程安全嗎?
- 14. NSThread線程安全實現初始化。
- 15. 如何在使用集合時實現線程安全緩存機制?
- 16. 使用線程安全集合的多個線程
- 17. 在異步任務和redis的django中的線程安全
- 18. C++中的異步線程安全日誌記錄
- 19. 如何使使用隊列線程安全的異步方法
- 20. 同步vs線程安全集合vs原子包裝類vs鎖
- 21. .NET異步套接字超時檢查線程安全
- 22. TPL異步靜態方法調用線程安全
- 23. 跟蹤異步加載與線程安全嗎?
- 24. 線程安全異步非重入任務
- 25. 異步線程
- 26. 使用C++中的futures,異步和線程實現搜索11
- 27. 如何實現一個真正的異步Java線程
- 28. 安全地同步COM線程
- 29. 爲線程安全同步NSMutableArray?
- 30. 線程安全的數據集
Caliburn Micro擁有一個可以關閉和打開的IsNotifying屬性的Bindable集合。我沒有在多線程互斥環境中使用它。但是,這是值得一試的。 – Jeremiah 2012-03-13 21:05:09