Partager via


Optimisation des performances : liaison de données

La liaison de données WPF (Windows Presentation Foundation) offre un moyen simple et cohérent aux applications de présenter et d’interagir avec les données. Les éléments peuvent être liés à des données provenant de diverses sources de données sous la forme d’objets CLR et XML.

Cette rubrique fournit des recommandations sur les performances de la liaison de données.

Comment les références de liaison de données sont résolues

Avant de discuter des problèmes de performances de liaison de données, il est utile d’explorer comment le moteur de liaison de données WPF (Windows Presentation Foundation) résout les références d’objets pour la liaison.

La source d’une liaison de données WPF (Windows Presentation Foundation) peut être n’importe quel objet CLR. Vous pouvez lier des propriétés, des sous-propriétés ou des indexeurs d’un objet CLR. Les références de liaison sont résolues à l’aide de la réflexion Microsoft .NET Framework ou d'une méthode ICustomTypeDescriptor. Voici trois méthodes permettant de résoudre les références d’objet pour la liaison.

La première méthode implique l’utilisation de la réflexion. Dans ce cas, l’objet PropertyInfo est utilisé pour découvrir les attributs de la propriété et fournit l’accès aux métadonnées de propriété. Lorsque vous utilisez l’interface ICustomTypeDescriptor, le moteur de liaison de données utilise cette interface pour accéder aux valeurs de propriété. L’interface ICustomTypeDescriptor est particulièrement utile dans les cas où l’objet n’a pas d’ensemble statique de propriétés.

Les notifications de modification de propriété peuvent être fournies en implémentant l’interface de INotifyPropertyChanged ou en utilisant les notifications de modification associées au TypeDescriptor. Toutefois, la stratégie recommandée pour l’implémentation des notifications de modification de propriété consiste à utiliser INotifyPropertyChanged.

Si l’objet source est un objet CLR et que la propriété source est une propriété CLR, le moteur de liaison de données WPF (Windows Presentation Foundation) doit d’abord utiliser la réflexion sur l’objet source pour obtenir le TypeDescriptor, puis rechercher un PropertyDescriptor. Cette séquence d’opérations de réflexion peut prendre beaucoup de temps du point de vue des performances.

La deuxième méthode de résolution des références d’objet implique un objet source CLR qui implémente l’interface INotifyPropertyChanged et une propriété source qui est une propriété CLR. Dans ce cas, le moteur de liaison de données utilise la réflexion directement sur le type source et obtient la propriété requise. Il ne s’agit toujours pas de la méthode optimale, mais elle coûte moins cher dans les exigences de l’ensemble de travail que la première méthode.

La troisième méthode de résolution des références d’objets implique un objet source qui est un DependencyObject et une propriété source qui est un DependencyProperty. Dans ce cas, le moteur de liaison de données n’a pas besoin d’utiliser la réflexion. Au lieu de cela, le moteur de propriétés et le moteur de liaison de données résolvent la référence de propriété indépendamment. Il s’agit de la méthode optimale pour résoudre les références d’objets utilisées pour la liaison de données.

Le tableau ci-dessous compare la vitesse de liaison de données à la propriété Text d’un millier d’éléments TextBlock à l’aide de ces trois méthodes.

Liaison de la propriété Texte d’un TextBlox durée de liaison (ms) Temps de rendu – inclut la liaison (ms)
À une propriété d’un objet CLR 115 314
À une propriété d’un objet CLR qui implémente INotifyPropertyChanged 115 305
Vers un DependencyProperty d’un DependencyObject. 90 263

Liaison à des objets CLR volumineux

Il existe un impact significatif sur les performances lorsque vous liez des données à un seul objet CLR avec des milliers de propriétés. Vous pouvez réduire cet impact en divisant l’objet unique en plusieurs objets CLR avec moins de propriétés. Le tableau affiche les heures de liaison et de rendu pour la liaison de données à un seul objet CLR volumineux par rapport à plusieurs objets plus petits.

Liaison de données de 1 000 objets TextBlock durée de liaison (ms) Temps de rendu – inclut la liaison (ms)
Vers un objet CLR avec 1 000 propriétés 950 1 200
À 1 000 objets CLR dotés d’une propriété 115 314

Liaison à un ItemsSource

Considérez un scénario dans lequel vous avez un objet CLRList<T> qui contient une liste d’employés que vous souhaitez afficher dans un ListBox. Pour créer une correspondance entre ces deux objets, vous devez lier votre liste d’employés à la propriété ItemsSource du ListBox. Toutefois, supposons que vous avez un nouvel employé qui rejoint votre groupe. Vous pouvez penser que pour insérer cette nouvelle personne dans vos valeurs de ListBox liées, vous devez simplement ajouter cette personne à votre liste des employés et vous attendre à ce que cette modification soit reconnue automatiquement par le moteur de liaison de données. Cette hypothèse s’avérerait fausse ; en réalité, la modification ne sera pas répercutée automatiquement dans le ListBox. Cela est dû au fait que l’objet CLRList<T> ne déclenche pas automatiquement un événement modifié de collection. Pour que le ListBox prenne en compte les modifications, vous devrez recréer votre liste d’employés et la rattacher à la propriété ItemsSource du ListBox. Bien que cette solution fonctionne, elle introduit un impact énorme sur les performances. Chaque fois que vous réaffectez le ItemsSource de ListBox à un nouvel objet, le ListBox lève d’abord ses éléments précédents et régénère toute sa liste. L’impact sur les performances est amplifié si votre ListBox est mappé à un DataTemplate complexe.

Une solution très efficace à ce problème consiste à faire de votre liste d’employés une ObservableCollection<T>. Un objet ObservableCollection<T> déclenche une notification de modification que le moteur de liaison de données peut recevoir. L’événement ajoute ou supprime un élément d’une ItemsControl sans avoir à régénérer la liste entière.

Le tableau ci-dessous indique le temps nécessaire pour mettre à jour la ListBox (avec la virtualisation de l’interface utilisateur désactivée) lorsqu’un élément est ajouté. Le nombre de la première ligne représente le temps écoulé lorsque l’objet CLRList<T> est lié à la ListBoxde l’élément ItemsSource . Le nombre de la deuxième ligne représente le temps écoulé lorsqu’une ObservableCollection<T> est liée au ListBoxde l’élément ItemsSource. Notez les économies significatives de temps à l’aide de la stratégie de liaison de données ObservableCollection<T>.

Liaison de données de la propriété ItemsSource heure de mise à jour pour 1 élément (ms)
Vers un objet CLRList<T> 1656
Vers un ObservableCollection<T> 20

Lier un objet IList à un objet ItemsControl non IEnumerable

Si vous avez le choix entre lier un IList<T> ou un IEnumerable à un objet ItemsControl, choisissez l’objet IList<T>. La liaison de IEnumerable à ItemsControl oblige WPF à créer un objet enveloppe IList<T>, ce qui signifie que vos performances sont affectées par la surcharge inutile d’un deuxième objet.

Ne pas convertir d’objets CLR en XML uniquement pour la liaison de données.

WPF vous permet de lier des données au contenu XML ; Toutefois, la liaison de données au contenu XML est plus lente que la liaison de données aux objets CLR. Ne convertissez pas les données d’objet CLR en XML si la seule finalité est de liaison de données.

Voir aussi