Frage

Viele Typen in WPF stammen aus Freezable. Es bietet Unveränderlichkeit zu wandelbar POCO Objekte und offenbar für eine verbesserte Leistung in bestimmten Situationen erlaubt.

Hat jemand herausgefunden, dass das Einfrieren Objekte innerhalb ihrer WPF Anwendungsleistung erheblich verbessert hat? Wenn ja, dann welche Elemente gab den größten Unterschied in der Leistung, wenn sie gefroren ist?

(Beachten Sie, dass ich eine ähnlich, aber andere Frage auch)

War es hilfreich?

Lösung

Sie können in meinen Erfahrungen mit Freezable interessiert sein:

Ich schrieb einmal ein PDF-Viewer MuPDF verwendet, die Bitmaps macht, dass ich mit WPF machen. Was die Leistung hilft sehr, dass ich die Seite Bitmaps auf einem Hintergrund-Thread machen können, frieren sie, und sie dann an den UI-Thread übergeben. Es ist schön, dass WPF das Bild nicht kopieren Sie sie einzufrieren, sondern die Fähigkeit, all diese Vorbereitung auf einem Hintergrund-Thread zu tun, war der entscheidende Vorteil für mich.

Von dem, was ich verstehen, müssen alle Visuals eingefroren werden, so dass sie sicher durch den WPF-Thread machen gerendert werden. Wenn Sie große ungefroren Visuals machen, erhalten sie auf gefrorenen diejenigen geklont, wenn WPF sie macht. Wenn Sie Ihre statischen Bitmaps vorher einfrieren, kann WPF teilen nur den Zeiger mit dem Faden machen, ohne das Klonen. Nicht fixierte Objekte können auch wiederholt kopiert werden, wenn WPF ist nicht bekannt, ob das Objekt aus der letzten Zeit geändert wird es gemacht wurde. Gefrorene Objekte eliminieren die Notwendigkeit, dass alle diese Kopien.

Andere Tipps

Diese potentiellen Speicherlecks könnte passieren, wenn Sie die Bildsteuerung verwenden (und nicht Freeze-Methode):

a) Sie verwenden Bitmap als Bildquelle und lassen Sie nicht die Bitmap:

static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",UriKind.RelativeOrAbsolute));
m_Image1 = new Image();
m_Image1.Source = bi1; 
//bi1.Freeze() 
//if you do not Freeze, your app will leak memory.
MyStackPanel.Children.Add(m_Image1);

b) Sie können mehrere Bitmap als Bildquelle zuweisen und lassen Sie nicht alle der Bitmap Sie verwendet (ähnlich (a)). Dieser führte in .Net 3.5:

static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",
UriKind.RelativeOrAbsolute));
static BitmapImage bi2 = new BitmapImage(new Uri("Bitmap2.bmp",
UriKind.RelativeOrAbsolute));
bi2.Freeze();
m_Image1 = new Image();
//bi1.Freeze() 
//even though you are really using bi2 for Image Source, 
//you also need to Freeze bi1 it to avoid leak 
m_Image1.Source = bi1;  // use un-frozen bitmap, which causes the leak
m_Image1.Source = bi2;  // use frozen bitmap
MyStackPanel.Children.Add(m_Image1);

Quelle: WPF Leistung

Auch wenn Sie bereits die Antwort akzeptiert, wollte nur eine andere Version der Antwort anmelden, die mir besser geholfen.

MSDN (minor edit):

  

Wenn Sie die Kontrolle modifizieren sind Bezug auf nicht verwalteten Low-Level-Ressourcen halten! (ZB: Pinsel), würde jede Änderung hat diese Low-Level-Objekte regeneriert

     

Die freezable Klasse ist, was eine Bürste gibt die Möglichkeit,   finden die entsprechenden erzeugt, Low-Level-Objekte und aktualisieren   sie, wenn sie sich ändert. Wenn diese Fähigkeit aktiviert ist, wird die Bürste sagt   als "nicht gefroren."

     

Ein Freeze-Methode des freezable können Sie diese selbst aktualisierende deaktivieren   Fähigkeit. Sie können diese Methode verwenden, die Bürste werden zu lassen „eingefroren“ oder   unveränderbar. So Verbesserung der Leistung.

Und der Code die Nutzung zu erklären:

            Button myButton = new Button();
            SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);

            if (myBrush.CanFreeze)
            {
                // Makes the brush unmodifiable.
                myBrush.Freeze();
            }                
            myButton.Background = myBrush;        
            if (myBrush.IsFrozen) // Evaluates to true.
            {
                // If the brush is frozen, create a clone and modify the clone.
                SolidColorBrush myBrushClone = myBrush.Clone();
                myBrushClone.Color = Colors.Red;
                myButton.Background = myBrushClone;
            }
            else
            {
                // If the brush is not frozen, it can be modified directly.
                myBrush.Color = Colors.Red;
            }

Ich entwickelte eine High-Performance-Bildbetrachter-Anwendung. Wir hatten Code auf dem Back-End, das eine neue Bitmap jeden Frame erstellt und schrieb, dass Bitmap auf dem Bildschirm wie folgt:

Writeablebitmap wb = new WriteableBitmap();
//  < code to set the wb pixel values here >

// Push the bitmap to the screen
image.Source = wb;

Während des Tests haben wir festgestellt, dass es eine schreckliche Flackern war beim Gehen mehr als 30 FPS mit mäßig großen Bildern (1080p). Die Reparatur? frieren Sie einfach die Bitmap, bevor es die image.Source Einstellung. Keine weitere Produkt-Tötung Performance Bug. Heute versuche ich alles frieren ich kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top