none
Singletons et AppDomain RRS feed

  • 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
    dimanche 3 juillet 2011 14:00

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

     


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    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.

    mardi 5 juillet 2011 10:07
  • 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
    


     

    et celui du formulaire:

     

    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
    mercredi 6 juillet 2011 16:28
  • 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


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    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.

    jeudi 7 juillet 2011 11:49
  • 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
    lundi 11 juillet 2011 08:54
  • 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 :

     

    appDomain

     

    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


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    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.

    mardi 12 juillet 2011 12:13