IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Singleton et Multithreading


Sujet :

C#

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut Singleton et Multithreading
    En lien avec mon topic Conception Singleton et Multithreading

    Voici une implémentation théorique en C# qui reprend l'idée de mehdiing :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    	public class Singleton
    	{
    		static private Singleton _instance;
    		static private bool _verrou=false;
    		static private int _maxWaitingDuringTime=20000;
    		static public int MaxWaitingDuringTime
    		{
    			get{return _maxWaitingDuringTime;}
    			set{_maxWaitingDuringTime=value;}
    		}
     
    		static Singleton()
    		{
    			_instance=new Singleton();
    		}
    		private Singleton()
    		{
     
    		}
     
    		public static Singleton GetInstance()
    		{
    			int waitingDuringTime=0;
    			int baseWaitingLoop=100;
    			int iLoop=0;
    			while(true){
    				iLoop++;
    				//Console.WriteLine(Thread.CurrentThread.Name+": Waiting for Singleton");
    				Thread.Sleep(baseWaitingLoop*iLoop);
    				waitingDuringTime+=baseWaitingLoop*iLoop;
    				lock(_instance)
    				{
    					if(!_verrou) break;
    				}
    				if(waitingDuringTime>MaxWaitingDuringTime) throw new ThreadStateException("Waiting access for "+waitingDuringTime+" ms while max allowed is "+MaxWaitingDuringTime);
    			}
    			lock(_instance)
    			{
    				_verrou=true;
    			}
    			return _instance;
    		}
     
    		public static void Release(ref Singleton p_instance)
    		{
    			lock(_instance)
    			{
    				_verrou=false;
    				p_instance=null;
    			}
    		}
    	}
    Qu'en pensez-vous ?

  2. #2
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Pour ce qui est des Singleton en C#, jettes un oeil a cet article, ca devrait peut-etre t'aider :
    http://webman.developpez.com/article...rns/singleton/

    Sinon, pour une discussion plus longue (mais en anglais) :
    http://www.yoda.arachsys.com/csharp/singleton.html

    En note de bas de page, le pattern Singleton est le plus mal utilise de tous les patterns du GoF, dans 80% des cas, il est avantageusement remplace par une Factory (mais bon, c'est mon avis a moi que j'ai...)

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Pourquoi et comment une Factory pourrait remplacer un Singleton ?

  4. #4
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Souvent, les singleton sont utilises a mauvais escient.

    Le problème, c'est qu'un singleton introduit un couplage fort entre les classes qui sont des singletons et leurs consommateurs.

    Le but du singleton est normalement de limiter les acces a une ressource (par exemple, un port E/S, ou autre), dans quasiment tous les autres cas, une variable globale, une factory ou un outil dÍoC procurera le meme "service", le couplage fort en moins

    Apres, tout depends de ce que tu veux faire

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    ça m'intéresse ce que tu me dis là !

    En fait je voulais faire ceci :

    - un singleton pour faciliter l'accès à la configuration
    - un singleton pour l'accès au logger
    - un singleton pour centraliser/dispatcher des événements
    - un singleton pour l'accès à la base

    Tout un programme si je puis dire !
    Dans ces cas de figures précis peux-tu me suggérer autre choses que des singletons ?

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par behess Voir le message
    Voici une implémentation théorique en C# qui reprend l'idée de mehdiing :
    [...]
    Qu'en pensez-vous ?
    Ca me parait beaucoup, beaucoup trop compliqué pour être fiable...

    Regarde le lien indiqué par Philippe sur le site de Jon Skeet, la dernière implémentation proposée est à la fois simple et robuste. Je te la recopie ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public sealed class Singleton
    {
        Singleton()
        {
        }
     
        public static Singleton Instance
        {
            get
            {
                return Nested.instance;
            }
        }
     
        class Nested
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static Nested()
            {
            }
     
            internal static readonly Singleton instance = new Singleton();
        }
    }
    Ca combine lazy initialization et thread safety (désolé je trouve pas de traduction française appropriée pour ces termes )

    Après, le singleton n'est pas forcément la solution la plus appropriée dans ton cas, mais voilà au moins comment en faire un "fiable" (enfin je suppose, j'ai tendance à prendre les écrits de Jon Skeet pour parole d'évangile )

  7. #7
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Citation Envoyé par behess Voir le message
    - un singleton pour faciliter l'accès à la configuration
    Pourquoi ? Une factory toute bete marchera aussi bien

    - un singleton pour l'accès au logger
    La plupart des frameworks de log doivent deja gerer le cas

    - un singleton pour centraliser/dispatcher des événements
    Pourquoi un singleton ? Une queue centralisee, ca ne va pas ?

    - un singleton pour l'accès à la base
    Probablement une mauvaise idee...Si tu es en asp.net, ca va tout peter, si tu es en winform, ca revient au meme qu'avoir une variable globale...

    ...bon, je crois que tout le monde a compris que j'ai ma carte du mouvement contre la singletonite

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Citation:
    Envoyé par behess
    - un singleton pour faciliter l'accès à la configuration

    Pourquoi ? Une factory toute bete marchera aussi bien
    Une factory ? Ce n'est pas pour contruire l'objet de configuration, mais pour accéder de partout cet objet d'accès à la configuration.

    Citation:
    - un singleton pour l'accès au logger

    La plupart des frameworks de log doivent deja gerer le cas
    Pour simplifier les appels... ex : Logger.Warn("alerte à malibu !");
    Ce loggeur serait global et ne nécessiterait ainsi pas d'appels tordus à la log4net pour simplement logger un truc.


    Citation:
    - un singleton pour centraliser/dispatcher des événements

    Pourquoi un singleton ? Une queue centralisee, ca ne va pas ?
    Une queue ne peut-elle pas être un singleton ? L'intérêt du singleton est qu'on n'a pas à le passer en paramètre. Il est donc "global" et ce serait aussi le cas de la queue ici, non ? ou alors je ne vois pas comment tu veux procéder !


    Citation:
    - un singleton pour l'accès à la base

    Probablement une mauvaise idee...Si tu es en asp.net, ca va tout peter, si tu es en winform, ca revient au meme qu'avoir une variable globale...
    Je bosse en dotNet C# ; je passe par un objet Proxy pour accéder à des services distants. Le but ici serait de gérér la connexion à ce proxy de manière "globale" à l'application, de manière à ne pas encombrer le code de connexions redondante. Le singleton s'assurerait que toutes les demandes passerait par lui et donc auraient une connexion valide.

    ...bon, je crois que tout le monde a compris que j'ai ma carte du mouvement contre la singletonite
    Mais c'est super le singleton, mais c'est pas toujours facile à maîtriser.
    On le confond parfois avec le Pattern Classe Utilitaire

  9. #9
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Mais c'est super le singleton, mais c'est pas toujours facile à maîtriser.
    Bah non, je suis pas d'accord, c'est pas testable, et on s'en sert comme d'une classe globale, alors que ca a un but bien precis...

    Si ce dont tu as besoin, c'est d'une classe qui n'est instanciée qu'une fois parce que sinon tout ton programme peut se retrouver par terre, un singleton, c'est ce qu'il te faut...sinon, c'est dans le pire des cas une classe globale, et, dans le meilleur, un conteneur qui va te retourner les données adéquates

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Et en quoi c'est pas bien une classe globale ?

  11. #11
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Citation Envoyé par behess Voir le message
    Et en quoi c'est pas bien une classe globale ?
    Les classes globales sont sujettes aux effets de bord, traversent souvent les couches (parce qu'on se dit "tiens, j'ai déjà une classe globale qui fait ceci ou cela), et peuvent, si on en abuse, poser des problèmes de maintenance.

    En soit, ce n'est pas "mal" d'avoir une classe globale (comme ce n'est pas "mal" d'avoir un singleton), mais si on s'en sert à toutes les sauces (et c'est souvent le cas...), elles posent des problèmes.

    En particulier, si tu mets en place des tests unitaires, les variables globales comme les singletons vont venir t'empêcher de tester certaines parties de ton code (et du coté des "principes", elles violent la loi de Déméter)

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    C'est quoi la loi de Déméter ??? Jamais entendu parlé...

    Pour ce qui est des tests, il suffit de remplacer la classe du singleton par une classe de test avec une interface identique, je vois pas où est le problème ?

    Evidemment, je ne parle pas de classe avec état qui stockerait un quelconque état de l'application. Les singletons dont je parle sont principalement utilitaires.

    Par exemple : un composant possède une classe de type singleton permettant d'envoyer à l'extérieur des messages sur son état interne ; le singleton ne "stocke" rien, il ne fait que "passer" les messages et son statut de singleton à l'intérieur du composant lui permet d'être accessible à toutes les classes du composant sans devoir leur "passer" cet objet ou les "initialiser" avec cet objet.

    Et si on veut tester une classe, on utilise une version "de test" du singleton, tout simplement. Après il faut que ce soit bien documenté pour des raisons de lisibilité (les futurs mainteneurs devront savoir que les classes dépendent du singleton).

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par behess Voir le message
    C'est quoi la loi de Déméter ??? Jamais entendu parlé...
    Wikipedia is your friend

    A part ça... tu fais ce que tu veux, c'est ton code après tout
    Mais bon, il y a des chercheurs qui ont longuement réfléchi à toutes ces questions de conception et d'architecture, et qui en sont arrivés à certaines conclusions, admises par la plupart des développeurs. Si tu veux les ignorer, libre à toi, mais c'est à tes risques et périls

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Admettons que l'on procède par injection de dépendance.

    Par exemple avec le logger :

    - je produis :
    une interface ILogger avec les méthodes de log qui vont bien
    une interface ILoggerUser qui a une propriété ILogger Logger{get,set}

    - puis toutes mes classes implémentent ILoggerUser

    C'est ça ?

    L'avantage c'est que les appels ne changement pas puisque le singleton avait des méthodes statiques : Logger.Warn("alerte à malibu") reste le même.

    Par contre il faut prévoir le cas où il n'y a pas d'injection et donc créer un logger par défaut qui sera affecté dès le départ à ces propriétés ; ex : un logger vers la console uniquement.

    J'ai tout bon ?

    Par contre pour les injections comment je fais ? Surtout quand je les fais ? Je dois passer toutes mes instances en revue et leur affecter le logger à la chaine ? Ou alors je passe par une Factory qui va me fournir le logger à la demande ? Mais je deviens dépendant d'une Factory alors... au lieu d'un Singleton... quel est le bénéfice ? Arggglll .... au seccccccours !

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu n'as pas forcément besoin de cette interface ILoggerUser... tu pourrais faire quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ILogger logger = container.GetInstance<ILogger>();
    logger.Log("blabla");
    (où container est le container IoC)

    Par contre, il me semble qu'un singleton serait quand même pratique pour avoir un accès global au container... (Philippe, c'est toi l'expert là-dessus, arrête moi si je me trompe )

  16. #16
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    En fait, la plupart du temps, les conteneurs IOC open source proposent une classe statique pour faire la résolution, qq chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ObjectFactory.GetInstance<ILogger>();
    Donc, a moins de refaire un conteneur maison, pas la peine de se casser la nenette

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    En fait vous considérez qu'il est plus avantageux de n'avoir qu'un seul objet global (le conteneur Injecteur de dépendances) qui fournit tous les objets à la demande plutôt que plusieurs Singleton c'est ça ?

    Mais si on veut changer l'injecteur ? Il faut alors rajouter une couche d'abstraction.

    Mais pour un simple batch, c'est pas un peu compliqué ?

  18. #18
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Mais si on veut changer l'injecteur ? Il faut alors rajouter une couche d'abstraction.
    Tu peux utiliser le CommonServiceLocator, mais souvent, c'est un peu "too much"

    Après, pour un *simple* batch, deja, le Singleton, c'est probablement trop complique

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Si le Singleton c'est trop compliqué, qu'est-ce qui est moins compliqué et qui pourrait permettre de conserver un code clair ?

  20. #20
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Si le Singleton c'est trop compliqué, qu'est-ce qui est moins compliqué et qui pourrait permettre de conserver un code clair ?
    Ca depends ce que tu entends par un *simple batch*...

    Si c'est vraiment quelque chose de trivial, une classe globale marchera probablement aussi bien...apres, si c'est trivial, et que tu veux mettre un Singleton, lache toi

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Singleton et multithreading
    Par alladdin dans le forum Langage
    Réponses: 8
    Dernier message: 29/07/2010, 23h31
  2. Singleton et multithread
    Par totoche dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 25/05/2010, 18h05
  3. [Singleton] singleton et multithreading
    Par behess dans le forum Design Patterns
    Réponses: 17
    Dernier message: 24/09/2009, 18h33
  4. Singleton et multithreading
    Par Alp dans le forum C++
    Réponses: 17
    Dernier message: 06/08/2006, 02h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo