Wie stellen Sie sicher, WPF-releases große BitmapSource aus dem Speicher?
System: Windows XP SP3 .NET 3.5, 4 GB RAM, Dual 1,6 gHz
Ich habe eine WPF-Anwendung, Belastungen und übergänge (mit Storyboard-Animation) extrem große PNGs. Diese PNGs werden 8190x1080 in der Auflösung. Wie die Anwendung ausgeführt wird, erscheint das Zwischenspeichern der Bilder und der Arbeitsspeicher langsam schleicht sich. Irgendwann streikt das system und wirft die OutOfMemoryException.
Hier sind die Schritte, die ich nehme zurzeit, zu versuchen, diese zu lösen:
1)ich bin das entfernen die BitmapSource-Objekte aus dem app
2)ich bin Einstellung der BitmapSource BitmapCacheOption None, wenn ich laden Sie die BitmapSource
3)ich friere die BitmapSource, sobald es geladen ist.
4)ich bin löschen Sie alle Verweise auf das Bild, das verwendet die Quelle sowie alle Verweise auf die Quelle selbst.
5)Manuell aufrufen von GC.Collect() nach dem oben beschriebenen Schritte abgeschlossen haben.
In der Hoffnung, um herauszufinden, warum WPF hängt auf Speicher für diese Bilder und eine mögliche Lösung, um sicherzustellen, dass der verwendete Speicher zu laden ist richtig erholt.
InformationsquelleAutor discorax | 2009-11-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werden Sie sicherlich haben, setzen Sie sich in eine Menge Arbeit auf dieser. Ich denke, das Hauptproblem ist, dass BitmapCacheOption.Keine nicht verhindern, dass die zugrunde liegenden BitmapDecoder(s) zwischengespeichert werden.
Gibt es mehrere knifflige Lösungen, um diese so zu tun, als eine GC.Collect(), laden 300 kleine Bilder von über 300 verschiedenen Uris und aufrufen von GC.Sammeln Sie() erneut, aber das einfache ist einfach:
Anstelle des Ladens von einer Uri, nur konstruieren Stream und übergeben es an BitmapFrame Konstruktor:
Grund sollte diese Arbeit ist, dass das laden aus einem stream komplett deaktiviert den cache. Nicht nur die top-level-Quelle, die nicht im Cache, aber keiner der interne Decoder zwischengespeichert werden.
Warum BitmapCacheOption.OnLoad? Es scheint, eingängig, aber diese fahne hat zwei Effekte: Es aktiviert die Zwischenspeicherung, wenn die Zwischenspeicherung ist möglich, und es bewirkt, dass die Last zu passieren, an EndInit(). In unserem Fall ist die Zwischenspeicherung unmöglich, so dass alle es tut, weil es die Last sofort geschehen.
Natürlich werden Sie wollen, führen Sie diesen code aus Ihrem UI-thread, dann frieren die BitmapSource so können Sie bewegen Sie es über.
Können Sie sich auch Fragen, warum ich nicht verwenden BitmapCreateOptions.IgnoreImageCache. Andere als die Tatsache, dass caching ist unmöglich mit keine URI angegeben, die IgnoreImageCache nicht völlig ignorieren Sie die Bild-cache: Es werden nur ignoriert, es zum Lesen. Also selbst wenn IgnoreImageCache gesetzt ist, wird das geladene Bild wird noch eingefügt in den cache. Der Unterschied ist, dass das bestehende Bild in der cache wird ignoriert.
Ahh..es kompiliert, wenn ich BitmapImage statt BitmapSource. Nun, wie wird das Probleme verursachen? 🙂
Dieser Ansatz sieht vielversprechend aus so weit. Ich werde weiter testen.
Ja, ich meinte BitmapImage. Ich werde es korrigieren.
Für wer sich fragt, was
...
werden sollten, wenn Sie versuchen, ein Bild zu laden off der lokalen Festplatte, versuchen Sienew FileStream(path, FileMode.Open)
.InformationsquelleAutor Ray Burns