Optimieren der Leistung: ObjektverhaltenOptimizing Performance: Object Behavior

Wenn Sie das Verhalten von systeminternen WPFWPF-Objekten verstehen, können Sie Funktionalität und Leistung optimal miteinander vereinen.Understanding the intrinsic behavior of WPFWPF objects will help you make the right tradeoffs between functionality and performance.

Wenn Ereignishandler nicht aus Objekten entfernt werden, bleiben diese möglicherweise aktivNot Removing Event Handlers on Objects may Keep Objects Alive

Der Delegat, den ein Objekt an sein Ereignis übergibt, ist gewissermaßen ein Verweis auf dieses Objekt.The delegate that an object passes to its event is effectively a reference to that object. Aufgrund von Ereignishandlern können Objekte länger als erwartet aktiv sein.Therefore, event handlers can keep objects alive longer than expected. Wenn sie ein Objekt bereinigen, das registriert wurde, um auf ein Ereignis eines Objekts zu lauschen, ist es erforderlich, dass Sie diesen Delegaten entfernen, bevor Sie das Objekt freigeben.When performing clean up of an object that has registered to listen to an object's event, it is essential to remove that delegate before releasing the object. Wenn nicht benötigte Objekte weiter aktiv sind, erhöht dies die Speicherauslastung Ihrer Anwendung.Keeping unneeded objects alive increases the application's memory usage. Dies ist insbesondere dann der Fall, wenn das Objekt der Stamm einer logischen oder visuellen Struktur ist.This is especially true when the object is the root of a logical tree or a visual tree.

WPFWPF führt ein schwaches Ereignislistenermuster für Ereignisse ein, das dann nützlich sein kann, wenn die Beziehungen der Objektlebensdauer zwischen Quelle und Listener schwierig zu überwachen sind.introduces a weak event listener pattern for events that can be useful in situations where the object lifetime relationships between source and listener are difficult to keep track of. Einige vorhandene WPFWPF-Ereignisse verwenden dieses Muster.Some existing WPFWPF events use this pattern. Wenn Sie Objekte mit benutzerdefinierten Ereignissen implementieren, kann dieses Muster für Sie nützlich sein.If you are implementing objects with custom events, this pattern may be of use to you. Weitere Informationen finden Sie unter Schwache Ereignismuster.For details, see Weak Event Patterns.

Es gibt mehrere Tools, wie z.B. den CLR-Profiler und den Workingset-Viewer, die Informationen zur Speicherauslastung eines angegebenen Prozesses zur Verfügung stellen können.There are several tools, such as the CLR Profiler and the Working Set Viewer, that can provides information on the memory usage of a specified process. Der CLR-Profiler umfasst eine Reihe sehr nützlicher Ansichten des Belegungsprofils, darunter z.B. ein Histogramm der zugewiesenen Typen, Zuordnungs- und Aufrufdiagramme, eine Zeitachse mit den automatische Speicherbereinigungen verschiedener Generationen und der daraus entstehende Status des verwalteten Heaps nach diesen Bereinigungen sowie eine Aufrufstruktur, die Zuweisungen und Laden von Assemblys für jede Methode veranschaulicht.The CLR Profiler includes a number of very useful views of the allocation profile, including a histogram of allocated types, allocation and call graphs, a time line showing garbage collections of various generations and the resulting state of the managed heap after those collections, and a call tree showing per-method allocations and assembly loads. Weitere Informationen finden Sie unter .NET Framework Developer Center.For more information, see .NET Framework Developer Center.

Anhängigkeitseigenschaften und ObjekteDependency Properties and Objects

Im allgemeinen DependencyObject ist der Zugriff auf eine Abhängigkeits Eigenschaft eines nicht langsamer als der Zugriff auf eine CLR-Eigenschaft.In general, accessing a dependency property of a DependencyObject is not slower than accessing a CLR property. Der Aufwand für die Festlegung eines Eigenschafts Werts kann zwar geringfügig beeinträchtigt werden, aber das Erzielen eines Werts ist so schnell wie der Wert aus einer CLR-Eigenschaft.While there is a small performance overhead for setting a property value, getting a value is as fast as getting the value from a CLR property. Der kleine Leistungsaufwand wird durch die Tatsache verursacht, dass Abhängigkeitseigenschaften zuverlässige Funktionen unterstützen, wie z.B. die Datenbindung, die Animation, die Vererbung und das Formatieren.Offsetting the small performance overhead is the fact that dependency properties support robust features, such as data binding, animation, inheritance, and styling. Weitere Informationen finden Sie unter Übersicht über Abhängigkeitseigenschaften.For more information, see Dependency Properties Overview.

DependencyProperty-OptimierungenDependencyProperty Optimizations

Sie sollten Abhängigkeitseigenschaften in Ihrer Anwendung sorgfältig definieren.You should define dependency properties in your application very carefully. Wenn Sie nur die Metadatenoptionen von "Rendering Type" und keine anderen Metadatenoptionen AffectsMeasurewie z. b DependencyPropertyIf your DependencyProperty affects only render type metadata options, rather than other metadata options such as AffectsMeasure, you should mark it as such by overriding its metadata. Weitere Informationen über das Überschreiben oder Abrufen von Eigenschaftenmetadaten finden Sie unter Metadaten für Abhängigkeitseigenschaften.For more information about overriding or obtaining property metadata, see Dependency Property Metadata.

Möglicherweise ist es effizienter, mit einem Handler für Eigenschaftenänderungen die Messungs-, Anordnungs- und Rendering-Durchläufe manuell für ungültig zu erklären, wenn nicht alle Eigenschaftenänderungen „Messung“, „Anordnung“ und „Rendering“ betreffen.It may be more efficient to have a property change handler invalidate the measure, arrange, and render passes manually if not all property changes actually affect measure, arrange, and render. Möglicherweise möchten Sie einen Hintergrund nur dann erneut rendern, wenn ein Wert höher als ein festgelegter Grenzwert ist.For instance, you might decide to re-render a background only when a value is greater than a set limit. In diesem Fall würde Ihr Handler für Eigenschaftenänderungen nur „render“ für ungültig erklären, wenn der festgelegte Grenzwert überschritten wird.In this case, your property change handler would only invalidate render when the value exceeds the set limit.

Sie können eine Abhängigkeitseigenschaft nicht frei vererbenMaking a DependencyProperty Inheritable is Not Free

Registrierte Abhängigkeitseigenschaften sind standardmäßig nicht vererbbar.By default, registered dependency properties are non-inheritable. Allerdings können Sie eine Eigenschaft explizit vererbbar machen.However, you can explicitly make any property inheritable. Obwohl dies nützlich ist, beeinträchtigt das Konvertieren einer Eigenschaft in eine vererbbare Eigenschaft die Leistung, da die Zeit für das Aufheben der Validierung erhöht wird.While this is a useful feature, converting a property to be inheritable impacts performance by increasing the length of time for property invalidation.

Verwenden Sie RegisterClassHandler mit VorsichtUse RegisterClassHandler Carefully

Beim Aufrufen RegisterClassHandler von können Sie den Instanzstatus speichern. es ist jedoch wichtig zu beachten, dass der Handler für jede Instanz aufgerufen wird, was zu Leistungsproblemen führen kann.While calling RegisterClassHandler allows you to save your instance state, it is important to be aware that the handler is called on every instance, which can cause performance problems. Verwenden RegisterClassHandler Sie nur, wenn Ihre Anwendung erfordert, dass Sie den Instanzstatus speichern.Only use RegisterClassHandler when your application requires that you save your instance state.

Legen Sie den Standardwert für eine Abhängigkeitseigenschaft während der Registrierung festSet the Default Value for a DependencyProperty during Registration

Wenn Sie ein DependencyProperty erstellen, das einen Standardwert erfordert, legen Sie den Wert mithilfe der Standard Metadaten fest, die Register als Parameter an DependencyPropertydie-Methode von übergeben werden.When creating a DependencyProperty that requires a default value, set the value using the default metadata passed as a parameter to the Register method of the DependencyProperty. Nutzen Sie diese Vorgehensweise, statt den Eigenschaftswert in einem Konstruktor oder in jeder Instanz des Elements festzulegen.Use this technique rather than setting the property value in a constructor or on each instance of an element.

Festlegen des Werts der Metadaten der Eigenschaft mit der Register-MethodeSet the PropertyMetadata Value using Register

Beim Erstellen DependencyPropertyvon haben Sie die Möglichkeit, die PropertyMetadata mithilfe der Register -Methode oder OverrideMetadata der-Methode festzulegen.When creating a DependencyProperty, you have the option of setting the PropertyMetadata using either the Register or OverrideMetadata methods. Obwohl das Objekt über einen statischen Konstruktor verfügen kann, OverrideMetadataum aufzurufen, ist dies nicht die optimale Lösung und wirkt sich auf die Leistung aus.Although your object could have a static constructor to call OverrideMetadata, this is not the optimal solution and will impact performance. Legen Sie PropertyMetadata Registerfür eine optimale Leistung die während des Aufrufes fest.For best performance, set the PropertyMetadata during the call to Register.

Freezable-ObjekteFreezable Objects

Ein Freezable ist ein spezieller Objekttyp, der zwei Zustände aufweist: nicht fixiert und fixiert.A Freezable is a special type of object that has two states: unfrozen and frozen. Wenn Sie Objekte immer dann, wenn es möglich ist, fixieren, wird dadurch die Leistung Ihrer Anwendung verbessert und ihr Workingset reduziert.Freezing objects whenever possible improves the performance of your application and reduces its working set. Weitere Informationen finden Sie unter der Übersicht über Freezable-Objekte.For more information, see Freezable Objects Overview.

Jedes Freezable verfügt über Changed ein-Ereignis, das ausgelöst wird, wenn es sich ändert.Each Freezable has a Changed event that is raised whenever it changes. Änderungsbenachrichtigungen nehmen jedoch einiges an Anwendungsleistung in Anspruch.However, change notifications are costly in terms of application performance.

Sehen Sie sich das folgende Beispiel an Rectangle , in dem Brush jeweils das gleiche Objekt verwendet wird:Consider the following example in which each Rectangle uses the same Brush object:

rectangle_1.Fill = myBrush;
rectangle_2.Fill = myBrush;
rectangle_3.Fill = myBrush;
// ...
rectangle_10.Fill = myBrush;
rectangle_1.Fill = myBrush
rectangle_2.Fill = myBrush
rectangle_3.Fill = myBrush
' ...
rectangle_10.Fill = myBrush

Standardmäßig stellt WPFWPF einen Ereignishandler für das- SolidColorBrush Ereignis des Changed -Objekts bereit, um die- Rectangle Eigenschaft des Fill -Objekts für ungültig zu erklären.By default, WPFWPF provides an event handler for the SolidColorBrush object's Changed event in order to invalidate the Rectangle object's Fill property. In diesem Fall muss jedes Mal, SolidColorBrush wenn das- Changed Ereignis auslösen muss, die Rückruffunktion für jede Rectangle– aufrufen. die Ansammlung dieser Rückruf Funktionsaufrufe verursachen einen erheblichen Leistungsabfall.In this case, each time the SolidColorBrush has to fire its Changed event it is required to invoke the callback function for each Rectangle—the accumulation of these callback function invocations impose a significant performance penalty. Darüber hinaus ist es sehr ressourcenintensiv, Handler an diesem Punkt hinzuzufügen und zu entfernen, da die Anwendung dazu die gesamte Liste durchlaufen müssten.In addition, it is very performance intensive to add and remove handlers at this point since the application would have to traverse the entire list to do so. Wenn sich das SolidColorBrushAnwendungsszenario nie ändert, werden Sie die Kosten für eine unnötige Wartung Changed von Ereignis Handlern bezahlen.If your application scenario never changes the SolidColorBrush, you will be paying the cost of maintaining Changed event handlers unnecessarily.

Das Einfrieren Freezable einer kann die Leistung verbessern, da Sie nicht mehr Ressourcen zum Verwalten von Änderungs Benachrichtigungen aufwenden muss.Freezing a Freezable can improve its performance, because it no longer needs to expend resources on maintaining change notifications. In der folgenden Tabelle wird die Größe einer einfachen SolidColorBrush angezeigt, IsFrozen wenn die-Eigenschaft trueauf festgelegt ist.The table below shows the size of a simple SolidColorBrush when its IsFrozen property is set to true, compared to when it is not. Dies setzt voraus, dass ein Pinsel Fill auf die- Rectangle Eigenschaft von zehn-Objekten angewendet wird.This assumes applying one brush to the Fill property of ten Rectangle objects.

ZustandState GrößeSize
GefrorSolidColorBrushFrozen SolidColorBrush 212 Bytes212 Bytes
Nicht fixiertSolidColorBrushNon-frozen SolidColorBrush 972 Bytes972 Bytes

Im folgenden Codebeispiel wird dieses Konzept veranschaulicht:The following code sample demonstrates this concept:

Brush frozenBrush = new SolidColorBrush(Colors.Blue);
frozenBrush.Freeze();
Brush nonFrozenBrush = new SolidColorBrush(Colors.Blue);

for (int i = 0; i < 10; i++)
{
    // Create a Rectangle using a non-frozed Brush.
    Rectangle rectangleNonFrozen = new Rectangle();
    rectangleNonFrozen.Fill = nonFrozenBrush;

    // Create a Rectangle using a frozed Brush.
    Rectangle rectangleFrozen = new Rectangle();
    rectangleFrozen.Fill = frozenBrush;
}
Dim frozenBrush As Brush = New SolidColorBrush(Colors.Blue)
frozenBrush.Freeze()
Dim nonFrozenBrush As Brush = New SolidColorBrush(Colors.Blue)

For i As Integer = 0 To 9
    ' Create a Rectangle using a non-frozed Brush.
    Dim rectangleNonFrozen As New Rectangle()
    rectangleNonFrozen.Fill = nonFrozenBrush

    ' Create a Rectangle using a frozed Brush.
    Dim rectangleFrozen As New Rectangle()
    rectangleFrozen.Fill = frozenBrush
Next i

Durch geänderte Handler auf nicht fixierten Freezable-Objekte bleiben Objekte möglicherweise aktivChanged Handlers on Unfrozen Freezables may Keep Objects Alive

Der Delegat, den ein Objekt an Freezable das- Changed Ereignis eines-Objekts übergibt, ist tatsächlich ein Verweis auf dieses Objekt.The delegate that an object passes to a Freezable object's Changed event is effectively a reference to that object. Daher können Changed Ereignishandler die Objekte länger als erwartet beibehalten.Therefore, Changed event handlers can keep objects alive longer than expected. Wenn Sie ein Objekt bereinigen, das registriert wurde, um auf das Freezable -Ereignis Changed eines-Objekts zu lauschen, ist es von entscheidender Bedeutung, diesen Delegaten vor der Freigabe des-Objekts zu entfernen.When performing clean up of an object that has registered to listen to a Freezable object's Changed event, it is essential to remove that delegate before releasing the object.

WPFWPFChanged verknüpft Ereignisse auch intern.also hooks up Changed events internally. Alle Abhängigkeits Eigenschaften, die Freezable als Wert verwenden, lauschen z. b. automatisch auf Changed Ereignisse.For example, all dependency properties which take Freezable as a value will listen to Changed events automatically. Die Fill -Eigenschaft, die einen Brushannimmt, veranschaulicht dieses Konzept.The Fill property, which takes a Brush, illustrates this concept.

Brush myBrush = new SolidColorBrush(Colors.Red);
Rectangle myRectangle = new Rectangle();
myRectangle.Fill = myBrush;
Dim myBrush As Brush = New SolidColorBrush(Colors.Red)
Dim myRectangle As New Rectangle()
myRectangle.Fill = myBrush

Bei der Zuweisung von myBrush zu myRectangle.Fillwird ein Delegat, der auf Rectangle das-Objekt zurück zeigt, SolidColorBrush dem- Changed Ereignis des-Objekts hinzugefügt.On the assignment of myBrush to myRectangle.Fill, a delegate pointing back to the Rectangle object will be added to the SolidColorBrush object's Changed event. Dies bedeutet, dass folgender Code myRect nicht zur automatischen Speicherbereinigung berechtigt:This means the following code does not actually make myRect eligible for garbage collection:

myRectangle = null;
myRectangle = Nothing

In diesem Fall myBrush bleibt myRectangle immer noch aktiv und wird zurück aufgerufen, wenn Changed das Ereignis ausgelöst wird.In this case myBrush is still keeping myRectangle alive and will call back to it when it fires its Changed event. Beachten Sie, myBrush dass bei Fill der Zuweisung zur- Rectangle Eigenschaft einer neuen ein anderer Ereignishandler myBrushzu hinzugefügt wird.Note that assigning myBrush to the Fill property of a new Rectangle will simply add another event handler to myBrush.

Die empfohlene Vorgehensweise zum Bereinigen dieser Objekttypen besteht darin, den Brush aus der Fill -Eigenschaft zu entfernen, wodurch wiederum der Changed -Ereignishandler entfernt wird.The recommended way to clean up these types of objects is to remove the Brush from the Fill property, which will in turn remove the Changed event handler.

myRectangle.Fill = null;
myRectangle = null;
myRectangle.Fill = Nothing
myRectangle = Nothing

Virtualisierung der BenutzeroberflächeUser Interface Virtualization

WPFWPFbietet auch eine Variation des StackPanel Elements, das automatisch Daten gebundenen untergeordneten Inhalt "virtualisiert".also provides a variation of the StackPanel element that automatically "virtualizes" data-bound child content. In diesem Zusammenhang bezieht sich das Wort „virtualisieren“ auf eine Technik, mit der eine Teilmenge von Objekten aus einer größeren Menge von Datenelementen generiert wird, je nachdem, welche Elemente auf dem Bildschirm sichtbar sind.In this context, the word virtualize refers to a technique by which a subset of objects are generated from a larger number of data items based upon which items are visible on-screen. Es ist sowohl für den Arbeitsspeicher als auch für den Prozessor sehr aufwändig, eine große Menge an UI-Elementen zu generieren, wenn sich möglicherweise nur sehr wenige Elemente zu einer angegebenen Zeit auf einem Bildschirm befinden.It is intensive, both in terms of memory and processor, to generate a large number of UI elements when only a few may be on the screen at a given time. VirtualizingStackPanel( VirtualizingPaneldurch die von bereitgestellte Funktionalität) berechnet sichtbare Elemente und funktioniert mit dem ItemsControl ItemContainerGenerator ListBox von einem (z ListView. b. oder), um nur Elemente für sichtbare Elemente zu erstellen.VirtualizingStackPanel (through functionality provided by VirtualizingPanel) calculates visible items and works with the ItemContainerGenerator from an ItemsControl (such as ListBox or ListView) to only create elements for visible items.

Zur Leistungsoptimierung werden visuelle Objekte für diese Elemente nur generiert oder aktiv gehalten, wenn sie auf dem Bildschirm sichtbar sind.As a performance optimization, visual objects for these items are only generated or kept alive if they are visible on the screen. Wenn sie sich nicht mehr im sichtbaren Bereich des Steuerelements befinden, können die visuellen Objekte entfernt werden.When they are no longer in the viewable area of the control, the visual objects may be removed. Dies ist nicht zu verwechseln mit Datenvirtualisierung, bei der Datenobjekte nicht alle in der lokalen Auflistung vorhanden sind, sondern bei Bedarf einfließen.This is not to be confused with data virtualization, where data objects are not all present in the local collection- rather streamed in as needed.

Die folgende Tabelle zeigt die verstrichene Zeit zum hinzu TextBlock fügen und Rendern von VirtualizingStackPanel5000 Elementen zu einem StackPanel und einem.The table below shows the elapsed time adding and rendering 5000 TextBlock elements to a StackPanel and a VirtualizingStackPanel. In diesem Szenario stellen die Messungen die Zeit zwischen dem Anfügen ItemsSource ItemsControl einer Text Zeichenfolge an die-Eigenschaft eines Objekts dar, die dem Zeitpunkt entspricht, an dem die Panel-Elemente die Text Zeichenfolge anzeigen.In this scenario, the measurements represent the time between attaching a text string to the ItemsSource property of an ItemsControl object to the time when the panel elements display the text string.

HostpanelHost panel Renderingzeit (in ms)Render time (ms)
StackPanel 32103210
VirtualizingStackPanel 4646

Siehe auchSee also