Idées reçues sur les composants Windows Runtime

Idées reçues sur les composants Windows Runtime

Qu’est ce qu’un composant windows Runtime?

Lorsque l’on crée une nouvelle assembly dans visual studio nous avons deux choix possible :
– Soit une bibliothèque de classe classique
– Soit un composant Windows Runtime.

Type de dll

Un composant Windows Runtime est généralement utilisé pour partager du code écrit dans un autre langage que celui qu’on utilise.
Par exemple un composant Windows Runtime peut être écrit pour :
– lorsque l’on veut des performances native utilisation de C++ pour de l’encodage vidéo, et partager ce composant à d’autres langage comme C#,Vb.net ou WinJS…
– lors de la création de Background task il est obligatoire d’écrire un composant Windows Runtime.

Idées reçue sur les limitations des composants Windows Runtime

Or ces composants pour être interopérable avec tous les langages ont un nombre limitations importantes dont les plus contraignante pour un développeur C# sont :
– Toutes les classes déclarées dans ce composant doivent être sealed*
– Tout les membres public de la classe doivent être compatible avec les autres langages, donc on ne peut pas exposer une fonction retournant une task par exemple.

* La classe ne peut pas être hérité.

Donc ça veut dire que je ne peux jamais utilisé de les asyncs/await dans mon composant?

Faux si vos méthodes sont privées vous pouvez utiliser toute la puissance de C#/VB.net sans aucune limitation.

    public sealed class ToastTask : IBackgroundTask
    {

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
            ToastThemAll(deferral);
        }

        private async void ToastThemAll(BackgroundTaskDeferral deferral)
        {
               var api = new MyApi();
               var rep await = api.GetData();
               ...
        }

 

Puis je utiliser des dll PCL dans un composant Windows runtime?

Oui, vous pouvez parfaitement partager votre code entre une DLL PCL qui déclare vos appels à une API

Performance et Composant Windows runtime

Attention le fait d’utiliser un composant Windows runtime dans votre code peut avoir un impact important sur les performances.

La documentation MSDN explique qu’à chaque fois qu’on utilise un composant, celui-ci est « convertit ».

À chaque fois que vous accédez à une propriété ou appelez une méthode sur un composant Windows Runtime, un coût d’interopérabilité est induit. En fait, créer un objet Windows Runtime est plus coûteux en ressources que de créer un objet .NET. Cela est dû au fait que Windows Runtime doit exécuter du code qui est converti du langage utilisé pour créer votre application à celui du composant. En outre, si vous transmettez des données au composant, ces données doivent être converties du type géré au type non géré.

J’ai décidé de faire un test simple de création de collection pour prouver les dires de la MSDN.
Si je crée une collection dans un composant Windows Runtime et que je l’utilise dans une mon app la création est entre 10% et 30% plus lente, pourtant c’est la même fonction…

 public IEnumerable<Data> GetData()
 {
     int count = 100000;
     List<Data> data = new List<Data>();
     for (int i = 0; i < count; i++)
     {
            data.Add(new Data() { Index = i, Name = "Name" + i.ToString() });
     }
     return data;
 }

En utilisant un décompilateur on peut avoir une petite idée. Notre fonction GetData est transformée de la façon suivante :

public extern IIterable<Data> GetData();

Pour chaque classe publique une interface est générée.

	internal interface IDataClass
	{
		int Index
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			set;
		}
		string Name
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			set;
		}
	}

De ce fait quand vous écrivez une applis entièrement en C# préférez partager votre code à vos composant Windows runtime que le contraire.
Plutôt que d’utiliser de code dans votre composant Window runtime.

Dans une apps en C# utilisez le plus souvent possible les API .Net.

Le fait de mélanger les deux API celles Windows Runtime dégrade fortement les performances.
Les API commençant par : Windows.Data sont des composant Window Runtime
Tandis que celles par : System sont des API .NET.

Par exemple il est préférable d’utiliser :
System.Xml.XmlReader que Windows.Data.Xml.Dom.XmlDocument pour éviter les surcout de conversion en .NET.

Copier les objets Window Runtime dans les types .NET

La MSDN conseille fortement de copier les objets retourné par les composants dans des types .Net avant de les utiliser, notamment toutes les collections avant de les itérer.

Essayer d’effectuer le moins d’appels possible aux objects Windows Runtime

La MSDN conseille d’effectuer le moins d’appels possible aux objets Windows Runtime.
Car chaque appel est gourmand du fait qu’il y a conversion automatique de type pour votre langage.

L’exemple que j’ai donné plus haut confirme que même si le composant Windows Runtime est écrit dans le même langage il y a une conversion…

Sources

  1. Création de composants Windows Runtime
  2. Best practice lors de l’utilisation de composant Windows runtime

Remerciements

Merci à Toss Net pour la relecture.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Pin It on Pinterest