Optimisation des performances : liaison de données

La liaison de données Windows Presentation Foundation (WPF) 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 aux données 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.

Cette rubrique comprend les sections suivantes.

  • Comment sont résolues les références de liaison de données
  • Liaison à des grands objets CLR
  • Liaison sur un objet ItemsSource
  • Lier IList à ItemsControl non IEnumerable
  • Ne convertissez pas d'objets CLR en XML seulement pour la liaison de données.
  • Rubriques connexes

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

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

La source d'une liaison de données Windows Presentation Foundation (WPF) peut être tout objet CLR. Vous pouvez créer une liaison avec des propriétés, sous-propriétés ou indexeurs d'un objet CLR. Les références de liaison sont résolues en utilisant la réflexion Microsoft .NET Framework ou un ICustomTypeDescriptor. Voici trois méthodes permettant de résoudre des 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é. Lors de l'utilisation de 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 de jeu statique de propriétés.

Les notifications de modification des propriétés peuvent être fournies en implémentant l'interface INotifyPropertyChanged ou en utilisant les notifications de modification associées au TypeDescriptor. Toutefois, la stratégie privilégiée pour implémenter les notifications de modification des propriétés est d'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 Windows Presentation Foundation (WPF) doit utiliser en premier la réflexion sur l'objet source pour obtenir le TypeDescriptor, puis effectuer une requête pour un PropertyDescriptor. Cette séquence d'opérations de réflexion peut potentiellement prendre beaucoup de temps d'une perspective de performance.

La deuxième méthode pour résoudre 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 directement la réflexion sur le type de source et obtient la propriété requise. Ce n'est pas encore la méthode optimale, mais elle sera plus avantageuse en terme de spécifications de jeu de travail que la première méthode.

La troisième méthode pour résoudre des références d'objet implique un objet source DependencyObject et une propriété source DependencyProperty. Dans ce cas, le moteur de liaison de données n'a pas besoin d'utiliser la réflexion. À la place, le moteur de propriété et le moteur de liaison de données résolvent ensemble la référence de propriété de manière indépendante. C'est la méthode optimale pour résoudre des références d'objet utilisées pour la liaison de données.

La table suivante compare la vitesse des données liant la propriété Text de mille éléments TextBlock utilisant ces trois méthodes.

Liaison de la propriété Text d'un TextBlock

Temps de liaison (ms)

Temps de rendu -- inclut la liaison (ms)

Sur la propriété d'un objet CLR

115

314

Sur une propriété d'un objet CLR qui implémente INotifyPropertyChanged

115

305

Sur une DependencyProperty d'un DependencyObject.

90

263

Liaison à des grands objets CLR

Il y a un impact sur les performances significatif lorsque vous liez les données avec un objet CLR unique 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. La table montre les temps de liaison et de rendu pour la liaison de données avec un grand objet CLR unique contre plusieurs objets plus petits.

Liaison de données de 1000 objets TextBlock

Temps de liaison (ms)

Temps de rendu -- inclut la liaison (ms)

Sur un objet CLR avec 1000 propriétés

950

1200

Sur 1000 objets CLR avec une propriété

115

314

Liaison sur un objet ItemsSource

Considérez un scénario dans lequel vous avez un objet CLR List<T> qui comporte une liste d'employés que vous souhaitez afficher dans ListBox. Pour créer une correspondance entre ces deux objets, vous devrez lier votre liste d'employés à la propriété ItemsSource de la ListBox. Toutefois, supposez qu'un nouvel employé a rejoint votre groupe. Vous pouvez penser que pour insérer cette nouvelle personne dans vos valeurs ListBox limitées, il vous suffirait d'ajouter cette personne à votre liste d'employés et d'attendre que cette modification soit reconnue automatiquement par le moteur de liaison de données. Cette hypothèse vous prouverait le contraire ; en réalité, la modification ne se sera pas répercutée automatiquement dans la ListBox. La raison est que l'objet CLR List<T> ne déclenche pas automatiquement de collection d'événement modifié. Afin que la ListBox récupère les modifications, vous devriez recréer votre liste d'employés et la rattacher à la propriété ItemsSource de la ListBox. Bien que cette solution fonctionne, elle engendre un impact énorme sur les performances. Chaque fois vous réaffectez le ItemsSource de la ListBox à un nouvel objet, la ListBox rejette d'abord ses éléments précédents et régénère sa liste entière. L'impact sur les performances est accru si votre ListBox mappe sur un DataTemplate complexe.

Une solution très efficace à ce problème est de transformer votre liste d'employés en 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'un ItemsControl sans qu'il soit nécessaire de régénérer la liste entière.

La table suivante montre le temps qu'il faut pour mettre à jour la ListBox (avec la virtualization d'interface utilisateur désactivés) lorsqu'un élément est ajouté. Le nombre dans la première ligne représente le temps écoulé lorsque l'objet CLRList<T>est lié au ItemsSource de l'élément ListBox. Le nombre dans la deuxième ligne représente le temps écoulé lorsqu'une ObservableCollection<T> est liée au ItemsSource de l'élément ListBox. Notez les gains de temps significatifs à l'aide de la stratégie de liaison de données ObservableCollection<T>.

Liaison de données de l'ItemsSource

Temps de mise à jour pour 1 élément (ms)

Sur un objet CLR List<T>

1656

Sur une ObservableCollection<T>

20

Lier IList à 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 sur un ItemsControl force WPF à créer un objet IList<T> de wrapper, ce qui signifie que vos performances subissent l'impact du traitement inutile d'un deuxième objet.

Ne convertissez pas d'objets CLR en XML seulement pour la liaison de données.

WPF vous autorise à lier des données sur du contenu XML ; toutefois, la liaison de données sur du contenu XML est plus lente que la liaison de données sur des objets CLR. Ne convertissez pas de données d'objet CLR en XML si le seul but est pour la liaison de données.

Voir aussi

Tâches

Procédure pas à pas : mise en cache de données d'application dans une application WPF

Concepts

Optimisation des performances des applications WPF

Planification des performances des applications

Optimisation des performances : tirer parti du matériel

Optimisation des performances : disposition et conception

Optimisation des performances : graphiques 2D et acquisition d'images

Optimisation des performances : comportement d'objets

Optimisation des performances : ressources d'application

Optimisation des performances : texte

Optimisation des performances : autres recommandations

Vue d'ensemble de la liaison de données