2013-03-28 35 views
3

我有一個c#應用程序,用戶通過使用拖動&刪除來使用wpf樹視圖來完成一些業務工作。 Undo堆棧提供了一些用戶功能,從一開始就回滾所有內容,並且約有500步左右的限制。c#檢測對象太多時

因此,如果這些對象引用位於undostack內部,GC將不被允許最終確定它們,因爲用戶可能需要它。

現在使用複製和粘貼功能,軟件測試人員可以採用這種方式,並在對方內部複製2個節點,然後重複此操作。 20次,這意味着通過從2,4,8,16,32克隆到最終1048576,對象數量增長。因此,複製操作可能導致例如創建1048576更多的對象,所以撤銷堆棧將存儲1048576對象引用,用於一個撤消步驟。 測試人員可以很容易地創建此應用程序崩潰:

類型'System.OutOfMemoryException'的異常被拋出。

因此,限制撤銷堆棧並不能解決太多對象的問題。

除此之外,沒有那麼多對象的用例,我只想簡單地放在安全的一面。

在MSDN告訴我:

要確保你有供內部使用足夠的內存和新的管理 對象。

我如何在我的情況下實現這一點,保持撤消功能?

+0

'try {} catch {}'? – Nolonar 2013-03-28 11:22:19

+0

好的,但是當對象數量已經增長太高時,這將是一種解決方法。第二,根據框架中當前的NET內存管理情況,存在發生異常的地方。將任何對象的每個「創建」放在try-catch內的任何類中都是一項巨大的工作。 – deafjeff 2013-03-28 11:29:40

回答

1

最簡單的方法是序列化您的對象並將其保存在磁盤上,以便在需要撤消時可以加載它們。

這裏的關鍵概念是序列化。你的對象應該可序列化來做到這一點。在需要時,您可以反序列化這些對象並加載到內存中。

+0

「這裏的關鍵概念是序列化」 - 我聽說過,謝謝 – deafjeff 2013-03-28 11:40:04

+0

數據可以增長2的冪然後這將推動撤銷限制高一點,當然不是500。也許OP可以實現某種引用計數 - 如果一個對象在兩個撤消步驟中是相同的,只需增加引用計數而不是將內容保存在內存中。 – Patko 2013-03-28 12:38:58

1

我會推薦你​​避免玩GC。我會考慮改變你的業務邏輯(可能是限制複製?)。另外,也許你可以在磁盤上的某個地方存儲(堅持)你的撤消步驟,abd允許它們從內存中消失。

1

爲了方便起見,您可以考慮使用MemoryFailPoint來更容易地發現異常。 OutOfMemory異常處理比其他處理更爲棘手,您可以使用MemoryFailPoint類降低獲得OOM異常的機會。

話雖如此,如其他答案中所述,將序列化撤銷堆棧或更改您的業務邏輯以避免無限制地複製/粘貼將更爲可取。