Sonntag, Mai 31, 2020

Faul singleton in einer Multithread-c# – Anwendung

Arbeite ich an einem Multithread-c# – Anwendung, die nutzen eines WCF web service. Die Verbindung zu dem webservice haben ein bestimmtes Zeitlimit, das wir uns definieren können und danach wird es enger. Ich bin auf der Suche um die Verbindung zu speichern, um die web-service-Nutzung des singleton-Klasse. Ich werde versuchen, die Instanz wie folgt :

CLazySingleton ins = CLazySingleton.Instance;
string connection = CLazySingleton.abc;

Unten ist der code für die singleton-Klasse :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LazySingleton
{
    public class CLazySingleton
    {
        private static readonly Lazy<CLazySingleton> _instance
            = new Lazy<CLazySingleton>(() => new CLazySingleton());
        private static readonly object ThreadLock = new object();
        public static string abc;  
        //I will use the service connection object in place of 'abc' in the application
        //assume that 'abc' is storing the connection object    

        private CLazySingleton()
        { }

        public static CLazySingleton Instance
        {
            get
            {   
                if (abc == null)
                {
                    lock (ThreadLock)
                    {
                        //Make the connection
                        abc = "Connection stored in this variable";
                        Console.WriteLine("Connection Made successfully");
                        return _instance.Value;
                    }                    
                }
                else
                {
                    return _instance.Value;
                }
            }
        }
    }
}

Meine Fragen sind :
1. Würde dieser code in der Lage sein, um zu kümmern, mehrere threads versuchen, um die Instanz in der gleichen Zeit ? Dies ist derzeit meine größte Sorge.
2. Kann ich eine bessere Lösung dafür ?
3. Benötige ich für die Verwendung von ‚lock‘ hier oder über Lazy-Ansatz kümmert sich um multithreads zu versuchen, um die Instanz ?

Jede mögliche Hilfe würde geschätzt.

Dank !

Check out this Artikel von Jon Skeet. Es macht einen guten job, darüber zu diskutieren, das Singleton-Muster. yoda.arachsys.com/csharp/singleton.html
Ich habe einige Zweifel auf Ihrem Ansatz. Warum müssen Sie pflegen ein Singleton für die Verbindung? Ist es ein problem, wenn jeder thread bekommt seinen eigenen proxy/connection? Und da es ein web-Dienst, den ich nicht voraussehen, keine Probleme, wenn Sie viele verbindungen. — Um besser zu verstehen welche Art von Objekt das ist Ihre „Verbindung“?
Sie brauchen nicht die Sperre

InformationsquelleAutor Anubhav Sharma | 2013-03-05

3 Kommentare

  1. 9

    Laut Microsoft ist Lazy Initialisierung – Dokumentation unter dem Abschnitt „Thread-Safe „Initialisierung“:

    Standardmäßig Faul – Objekte sind thread-sicher.

    Mit diesem im Verstand, Ihre abc Feld muss nicht statisch sein. Wie man mit einem Lazy<T> zu instanziieren Sie Ihr singleton ist, es ist sicher zu initialisieren, die Verbindung in der CLazySingleton Konstruktor.

    Hallo Richard, Danke für die Antwort. Sie haben einen guten Punkt. Auch ich dachte darüber nach das gleiche. Aber meine Frage ist, wenn ich Schreibe, die Logik, um die Verbindung im Konstruktor, wie sollte ich es schaffen ein Szenario, in dem die Verbindung bekommt abgelaufen ist, von selbst nach einer bestimmten timeout. In diesem Fall ist das Feld abc wird ungültig und die singleton-Klasse würde halten, nach der Rückkehr, dass Sie als null ist, nur als Konstruktor wird nicht erneut aufgerufen werden. Ich hoffe, dass ich liefern konnte, was ich meine.
    Ich denke, mit Singleton ist nicht das richtige Muster hier, eigentlich brauchen Sie nicht zu verwalten, Ihre Verbindung auf diese Weise. Und, sind Sie sicher, dass Sie einen Webdienst aufrufen, weil das, was ist die Art von timeout, die Sie hier erwähnen?

    InformationsquelleAutor Richard

  2. 5

    Einfache Nutzung ThreadSafetyMode

     Lazy<MergeSort> ty = new Lazy<MergeSort>(LazyThreadSafetyMode.ExecutionAndPublication);
    Faul Standard-Konstruktor verwendet LazyThreadSafetyMode.ExecutionAndPublication, es ist thread-safe standardmäßig.
    Danke, ich werde sicherlich versuchen, diese.

    InformationsquelleAutor TalentTuner

  3. 4

    Würde dieser code in der Lage sein, um zu kümmern, mehrere threads versuchen, um die Instanz in der gleichen Zeit ?

    In Ihrem Szenario kann der „abc“ – Feld initialisiert zweimal. Stellen Sie sich die situation, das „abc“ der Variablen null ist. Erste thread in dem „lock“ sperren, bevor die Wertzuweisung. Der zweite thread wartet, bevor die Sperre. So der erste thread wird initialisiert, die „abc“ und der zweite thread neu initialisiert werden (Ihre überprüfung auf null ist, außerhalb der Sperre, das ist der Grund). Aber vielleicht ist dies nicht etwas, das man fürchten sollte.

    Kann ich eine bessere Lösung dafür ?

    Ja, Sie können. Lassen Sie mich beschreiben, es im letzten block dieser Antwort.

    Benötige ich für die Verwendung von ‚lock‘ hier oder über Lazy-Ansatz kümmert sich um multithreads zu versuchen, um die Instanz ?

    Erstellung der Value-Eigenschaft in der Lazy-Klasse ist thread-sicher. In deinem Szenario würde ich verwenden, den Vorteil der Eigenschaft IsValueCreated von Faul<> Klasse. Sie benötigen noch die Schraubensicherung-Objekt als gut. Nur eine weitere Sache ist, dass wenn Sie der Eigenschaft Value des Lazy<> – Klasse, IsValueCreated Eigenschaft true zurück (das ist der trick 😉 )

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace LazySingleton
    {
        public class CLazySingleton
        {
            private static readonly Lazy<CLazySingleton> _instance
                = new Lazy<CLazySingleton>(() => new CLazySingleton());
            private static readonly object ThreadLock = new object();
            public static string abc;  
            //I will use the service connection object in place of 'abc' in the application
            //assume that 'abc' is storing the connection object    
    
            private CLazySingleton()
            { }
    
            public static CLazySingleton Instance
            {
                get
                {   
                    if (_instance.IsValueCreated)
                    {
                        return _instance.Value;
                    }
                    lock (ThreadLock)
                    {
                        if (abc == null)
                        {
                            abc = "Connection stored in this variable";
                            Console.WriteLine("Connection Made successfully");
                        }
                    }
                    return _instance.Value;
                }
            }
        }
    }

    InformationsquelleAutor David Gregor

Kostenlose Online-Tests