Auteur de questions
Singletons et AppDomain

Discussion générale
-
La « littérature » semble dire qu’une classe de structure Singleton est unique dans un AppDomain or, tous les essais que j’ai faits me montre que le singleton est unique dans l’application et ne se partage pas avec les autres applications du même domaine (ce qui somme toutes et logique puisque la structure des singleton est purement « logicielle »
Il y probablement quelque-chose qui m’échappe, mais quoi ? J’aimerais que quelque me mette sur la voie car j’ai justement besoin de crées une DDL concernent une classe unique à un ensemble d’applications.
Merci d’avance
BB- Type modifié Ciprian Duduiala dimanche 10 juillet 2011 07:56 attente de feedback
Toutes les réponses
-
Bonjour,
Pouvez-vous nous montrer le code de votre classe Singleton pour pouvoir reproduire le contexte de votre erreur ? Normalement, ce que vous voulez faire est possible avec une classe Singleton, mais vu qu’il y a des limitations quand on parle de multithreading vos tests peuvent échouer dans certaines situations.
Cordialement,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
Bonjour Ciprian,
Ci-dessous le singleton et la méthode que j’utilise pour le tester :
J’ai créé une solution qui contient 2 « Assemblies » :
· une bibliothèque de classes dans laquelle se trouve le singleton.
· Un formulaire Windows qui permet d’utiliser le singleton (en Projet de démarrage)
Le singleton ne contient rien d’autre que sa structure, Il affiche juste un message dans la fenêtre d’exécution en indiquant si c’est une nouvelle instance ou l’instance existante ainsi que l’AppDomain qui permet de vérifier si le singleton et le formulaire sont dans le même domaine.
Voici le test que je fais pour vérifier si le singleton est unique dans l’AppDomain :
1. Je démarre le projet sur le formulaire Windows
2. Puis je crée 2 instances supplémentaires du formulaire (si vous faites la manipe (VS2010) vous constaterez que les instances au-delà de la 1ère sont dans le même AppDoimain)
3. Je crée le premier singleton à l’aide la 2eme (ou 3eme) instance. Qui m’indique « Nouvelle instance ».
4. Tant que j’utilise le même formulaire pour me « raccorder »« aux instances je reçois bien le message « instance existante »
5. Si j’utilise l’autre formulaire, il crée sa propre lignée (« Nouvelle instance ») au lieu de se raccorder sur l’existante.
D’ailleurs je ne vois pas pourquoi cela serait autrement !
En fait, le singleton était une approche de mon problème, ce que je cherche réellement et de pouvoir partager une DLL (les données principalement) entre plusieurs assemblies . Je ne cherche pas un moyen détourné du type Fichiers en mémoire/ pipes ou autres canaux d’échange, je veux juste savoir s’il y a moyen de récupérer « un pointeur » sur l’instance existante et de l’utiliser.
Voici le code pour le singleton:
Public NotInheritable Class Singleton Private Shared _Instance As Singleton Private Shared ReadOnly _SyncRoot As New Object Private Sub New() End Sub Shared ReadOnly Property Instance As Singleton Get If IsNothing(_Instance) Then SyncLock _SyncRoot If IsNothing(_Instance) Then _Instance = New Singleton Debug.Print("Nouvelle instance du Singleton") End If End SyncLock Else Debug.Print("L'instance du Singleton existe") End If Debug.Print("Domaine du Singleton : {0}", AppDomain.CurrentDomain.FriendlyName) Return _Instance End Get End Property End Class
Imports Singleton Public Class Form1 Dim obj As Singleton.Singleton Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Debug.Print("Domaine de WF : {0}", AppDomain.CurrentDomain.FriendlyName) obj = Singleton.Singleton.Instance End Sub End Class
Cordialement,
Bernard
BB -
Bonjour,
J’ai testé votre code et j’ai obtenu le même résultat. Comme le concept de singleton est un design pattern qui n’appartient pas à .NET c’est la décision du programmeur comment implémenter sa classe et où est l’instance singleton disponible (voir cette discussion très intéressante – surtout la réponse de Svante), mais il semble qu’avec votre code et l’exemple qu’on trouve sur MSDN l’instance singleton n’est pas unique dans l’App Domain et il est plutôt lie à chaque instance de l’application.
Une solution pour cette problème est d’utiliser les fonctions GetData et SetData de la classe AppDomain, qui vous permet enregistrer et récupérer l’instance au niveau d’AppDomain et sera unique (attention, il faut modifier l’exemple pour vos besoins). Pour Singleton dans plusieurs AppDomains vous pouvez aussi utiliser cet exemple.
Cordialement,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
Bonjour,
Et encore merci pour vos efforts.
J’avais déjà lu une partie des articles que vous me signalez, qui justement laissent à penser que le singleton est unique dans le domaine. J’ai essayé les fonctions GetData et SetData de l’AppDomain, néanmoins rein de changé avec ces tests non plus. En fait, la fonction ne retrouve jamais l’objet du dictionnaire. Tout se passe comme si des domaines différents renvoyaient le même CurrentDomain.FriendlyName.
J’ai lu en long en large et en travers ce que MSDN dit sur AppDomain et je suis sûr qu’il y a toujours quelque chose qui m’échappe. Les 2 derniers exemples font dériver leur classe à partir de MarshalByRefObject or ce type « régulation » est utile pour passer au travers de la barrière du domaine, cas de figure qui n’est pas le mien.
Cordialment,
Bernard
BB -
Bonjour,
Il semble que j’ai mal compris ce que vous voulez réaliser et j’ai aussi fait une grande erreur quand j’ai écrit les réponses antérieures parce que je n’ai pas testé les solutions présentées sur ces liens et à quoi on peut les utiliser. En plus, j’e n’ai pas payé attention à vous expliquer l’unicité d’un AppDomain dans un processus et je m’excuse pour vous donner une piste false.
Je m’explique : en fait la classe Singleton est bien instanciée une seule fois dans un AppDomain et vous avez bien compris toutes les explications lues sur different sites, mais il est très important comment les instances d’une application sont lancées. Quand on lance une application, un nouvel processus Windows est lancé qui va avoir ses propres AppDomains :
Si on lance la deuxième instance dans le même AppDomain ou dans un AppDomain enfant tout va bien avec les solutions proposées, mais si l’exécution est fait dans un nouveau processus (vous pouvez vérifier les processus existants avec Process Explorer), la classe Singleton est instanciée de nouveau, parce qu’on a un autre AppDomain avec le même nom et peut-être le même ID (1 le plus souvent), mais dans un autre processus (voir aussi cette discussion pour un autre résumé sur ce sujet).
C’est un peu étonnant qu’avant mon dernière post j’ai testé votre code, mais j’ai oublié qu’il ne faut pas lancer un nouvel processus pour pouvoir utiliser le concept Singleton.
Pour revenir à votre question initiale, vous dites :
le singleton est unique dans l’application et ne se partage pas avec les autres applications du même domaine
Comme je vous disait dans le premier post, il est possible le faire avec la classe Singleton, mais il faut s’assurer que les applications sont lancés dans le même AppDomain. Sinon, il faut utiliser Interprocess Communications pour partager les informations.
Cordialement,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.