Es klingt so, als ob das Hauptproblem, das Sie haben, nicht so sehr die Leistungsintensität der Anwendung ist (bei der Dinge wie Puffer mit fester Größe und statische Zuweisung helfen), sondern ihr Gesamtspeicherbedarf. Das lässt sich mit Virtualisierung in den Griff bekommen.
Mit Lazy Loading kommt man auf halbem Weg zum Ziel: Man erstellt das Objekt erst, wenn es benötigt wird. Das ist in Ordnung, aber je länger der Benutzer mit der Anwendung arbeitet und je mehr Objekte er in der Benutzeroberfläche besucht, desto mehr Objekte werden erstellt, und schließlich geht der Anwendung der Speicher aus.
Sie wollen also Objekte wegwerfen, die der Benutzer nicht mehr braucht. Herauszufinden, welche Objekte der Benutzer nicht braucht, kann ein schwieriges Problem sein, aber es kann auch so einfach sein wie die Annahme, dass der Benutzer das Objekt, das er am wenigsten benutzt hat, nicht braucht. Dazu verwenden Sie einen LRU-Cache (Least-Recently-Use-Cache).
Dies ist völlig im Einklang mit dem MVVM-Muster. In Ihrer View-Klasse machen Sie Ihren Property Getter für das Objekt mit diesem Pseudocode:
if object hasn't been loaded
load object
add object to the LRU cache (whether you loaded it or not)
return object
Der LRU-Cache, den ich geschrieben habe führt eine einfache Warteschlange der darin enthaltenen Objekte. Wenn Sie dem Cache ein Objekt hinzufügen, wird es, wenn es noch nicht in der Warteschlange ist, nach hinten verschoben, und wenn es bereits in der Warteschlange ist, wird es nach hinten verschoben.
Wenn die Warteschlange ihre Kapazität erreicht hat, wenn Sie ein Objekt hinzufügen, wird das Objekt, das sich an der Spitze der Warteschlange befindet (d.h. dasjenige, das zuletzt verwendet wurde), entfernt und die DiscardingOldestItem
Veranstaltung.
Dieses Ereignis ist die Chance des Objekts, alles, was einen Verweis auf es hält (d.h. das View-Objekt, von dem es eine Eigenschaft ist), darüber zu informieren, dass es verworfen werden muss (wahrscheinlich durch Auslösen eines eigenen Ereignisses). Der Event-Handler des View-Objekts sollte zuerst das PropertyChanged
Ereignis. Wenn die Eigenschaft Getter aufgerufen wird, wenn es dies tut, gibt es eine Bindung irgendwo, die noch auf die Eigenschaft suchen, so dass es noch nicht verworfen werden sollte. (Außerdem wurde das Objekt, da der Getter aufgerufen wurde, gerade an das Ende der Warteschlange verschoben.) Andernfalls kann es weggeworfen werden.
(Beachten Sie, dass dieser kleine Tanz zu einer Endlosschleife wird, wenn mehr Objekte in der Benutzeroberfläche sichtbar sind, als der Cache aufnehmen kann, und Sie einen Stapelüberlauf erhalten).
Bei einem ausgefeilteren Ansatz würde der LRU-Cache damit beginnen, alte Elemente zu verwerfen, wenn der Speicherplatz der Anwendung knapp wird (er verwendet derzeit eine feste Kapazität). Das ist eine einfache Änderung, aber wenn Sie diese Änderung vornehmen, ist das im vorherigen Absatz beschriebene Szenario etwas, über das Sie mehr nachdenken müssen; ein sehr großes Objekt könnte dazu führen, dass die gesamte Benutzeroberfläche zusammenbricht.