[WPF] Augmenter les performances des ResourceDictionary

Le 17 juillet 2010 à 14:29

Quand vous déclarer un ResourceDictionary, cela crée une nouvelle instance de celui-ci. Mais si par exemple, vous avez des dizaines de contrôles personnalisés et que ceux-ci ont chacun un dictionnaire de ressource en commun, le même dictionnaire de ressource sera instancié plusieurs fois.

Pour remédier à ce problème, Christian Mosers, a crée la classe SharedResourceDictionary. Celle ci s’utilise de la même façon qu’un ResourceDictionary à la différence que cette fois ci, si un dictionnaire de ressource est instancié plusieurs fois, il sera en fait chargé qu’une seule fois.

Avec cette solution, il y aura un impact positif sur les performances et sur la mémoire !

[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", 
"WPFTutorial.Utils")]
 
/// <summary>
/// The shared resource dictionary is a specialized resource dictionary
/// that loads it content only once. If a second instance with the same source
/// is created, it only merges the resources from the cache.
/// </summary>
public class SharedResourceDictionary : ResourceDictionary
{
    /// <summary>
    /// Internal cache of loaded dictionaries 
    /// </summary>
    public static Dictionary<Uri, ResourceDictionary> _sharedDictionaries =
        new Dictionary<Uri, ResourceDictionary>();
 
    /// <summary>
    /// Local member of the source uri
    /// </summary>
    private Uri _sourceUri;
 
    /// <summary>
    /// Gets or sets the uniform resource identifier (URI) to load resources from.
    /// </summary>
    public new Uri Source
    {
        get { return _sourceUri; }
        set
        {
            _sourceUri = value;
 
            if (!_sharedDictionaries.ContainsKey(value))
            {
                // If the dictionary is not yet loaded, load it by setting
                // the source of the base class
                base.Source = value;
 
                // add it to the cache
                _sharedDictionaries.Add(value, this);
            }
            else
            {
                // If the dictionary is already loaded, get it from the cache
                MergedDictionaries.Add(_sharedDictionaries[value]);
            }
        }
    }
}

Et pour l’utiliser :

<ResourceDictionary.MergedDictionaries>
   <SharedResourceDictionary Source="/MyControlLibrary;component/Themes/Brushes.xaml"  />
</ResourceDictionary.MergedDictionaries>

A bientôt !

Commentaires (1) -

mde
mde
Il y a malheureusement un memory leak dans cet implementation. Le ResourceDictionary conserve une ref sur les contrôles qui l'utilisent ; ce qui empêche la GC.
S'il y a un gd nombre d'instanciation de contrôles de ce genre, le meroy leak est flagrant.

Je n'ai pas trouvé de work around pour le moment...

Ajouter un commentaire

biuquote
  • Commentaire
  • Prévisualiser
Loading

A propos de l'auteur

Mathieu Perrein - Software Solutions Manager, Software Architect, Trainer MCT, MSP de 2010 à 2012.

 

MSP

 

MSP

MSP

 MSPD

MCT

 

Facebook

 

Ce blog est strictement personnel et les opinions exprimées ici n'engagent donc que moi, et pas mon employeur.

Tags

Vous avez désactivé JavaScript ou bien vous possédez une ancienne version d'Adobe Flash Player. Téléchargez la dernière version de Flash Player.