Probleme mit singleton-Muster im inneren WCF-service-Methode
Ich werde gehen Sie vor und Vorwort dies mit den Worten: ich bin etwas neu auf WCF.
Ich arbeite an einer server-side-routine, die verantwortlich für eine große Menge business-Logik. Es ist zugänglich von einem client über WCF.
Mein main WCF-Methode ruft aus, um mehrere andere private-Methoden. Statt der übergabe um die "lookup-Daten", die ich brauche für die business-Logik für jedes private-Methode, ich habe mich für eine singleton-Instanz der Klasse DataProvider enthält alle diese "lookup-Daten".
Am Ende der routine, die ich "freigeben" die DataProvider-die Daten in der Nachschlagetabelle, so dass die nächste mal, wenn die routine ausgeführt wird, die neuesten Daten in der Nachschlagetabelle werden verwendet.
So, hier ein Vereinfachtes Beispiel:
public void Generate()
{
try
{
//populate singleton DataProvider with it's lookup data...
DataProvider.Instance.LoadLookupData();
//do business logic...
}
finally
{
//release provider's lookup data...
DataProvider.Release();
}
}
Dies funktioniert gut, solange ich nicht zwei verschiedene clients, die execute-Methode auf (oder nahe) der gleichen Zeit. Probleme auftreten, weil Sie teilen sich die gleiche singleton-Instanz und die Aufgabe, die zuerst fertig wird, lassen Sie die DataProvider-bevor die anderen abgeschlossen.
So...
Was sind meine Optionen hier?
Möchte ich vermeiden, durch um alle Daten in der Nachschlagetabelle, so dass das singleton-Muster (oder ein Derivat) scheint eine gute Wahl. Ich muss auch in der Lage sein, die Unterstützung mehrerer clients durch den Aufruf dieser Methode in der gleichen Zeit.
Glaube ich, dass der WCF-Dienst ist so konfiguriert, dass als "Pro-Anruf". Ich bin mir nicht sicher, ob es eine Möglichkeit zur Konfiguration eines WCF-Diensts, so dass der statische Speicher ist nicht geteilt zwischen service-Aufrufe.
Jede mögliche Hilfe würde geschätzt.
- Jemand korrigiert mich wenn ich hier falsch, aber die übergabe der Daten in der Nachschlagetabelle in einer anderen Klasse würde das nicht schaffen ganz neue Exemplare von allen seinen Daten, richtig? Wäre es nicht einfach nur eine Kopie der Referenz auf die Daten? (Es sei denn natürlich, es ist immer serialisiert in einer service-Grenze, das klingt nicht wahrscheinlich, dass in diesem Fall)
- Ich möchte verstehen, die Beweggründe der singleton-Klasse. Ist es etwas, das Sie erstellen nur einmal, und alle Anrufer an Ihre service benötigen, um die gleiche Instanz der Daten? Oder ist es etwas wie, dass eine Rückkehr Anrufer Ihren Dienst erhalten, sollten die gleichen Daten (session)?
- Der Grund für das "singleton" ist, dass die business-Logik schafft etwa 30+ verschiedene Arten von Objekten. Jeder braucht Zugang zu den Daten in der Nachschlagetabelle. Vielleicht war ich faul, aber ich hatte nicht das Gefühl, wie mit dem gleichen argument zu 30+ verschiedene Konstruktoren. Lol. Ich fühlte mich wie singleton war der sauberste Ansatz, so dass jedes Objekt, könnte problemlos den Zugriff auf die Daten in der Nachschlagetabelle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
WCF standardmäßig wird mit "Pro Call", was bedeutet, dass neue Instanz der WCF-service erstellt für jeden Kunden anrufen. Jetzt, da Sie singleton implementiert, obwohl neue Instanz der WCF erstellt, ist es dennoch ruft die singleton.
Wenn Sie möchten, erstellen, Suche, die erstellt für jeden Aufruf (wie Sie jetzt) Sie sollten es nicht als singleton. So wird jeder client ruft die Methode wird die neue Instanz der lookup-ich glaube, das war Ihre Absicht.
Jedoch, wenn Sie lookup, das ist nicht zu ändern, dass schnell, ich würde empfehlen, es zu teilen zwischen alle Anrufe, dies verbessert die Leistung der WCF-service. Sie müssen erklären, Ihre WCF-service als
Was dieser tut, ist erstellen Singleton automatisch für Sie von der WCF, so dass Sie nicht haben, es selbst zu tun, zweitens unterstützt es > 1 gleichzeitiger Benutzer (ConcurrencyMode.Mehrere).
Nun, wenn Sie Ihre Suche, die änderung und es muss neu geladen werden, nachdem einige Zeit, ich würde noch empfehlen die Verwendung
aber innen im code-cache, und dann verfallen Sie Ihren cache zu einer bestimmten Zeit oder relative Zeit (1 Stunden).
Hier sind einige links, die Ihnen helfen könnten:
3 Wege, um WCF-Instanz-management (Pro Aufruf, Pro Sitzung und Single)
Hoffe, das wird helfen.
ConcurrencyMode.Multiple
bedeutet, es können mehrere threads der gleichen Methode zur gleichen Zeit. Mit pro-nennen Sie eine einzige Instanz pro Anfrage, also multi-threading und Synchronisation nur dann Probleme, wenn man den Umgang mit statischen Variablen.//do business logic...
Die statischen Variablen in ein WCF-service, sind stets geteilt zwischen Instanzen unabhängig von der WCF InstanceContextMode Einstellung. Es scheint, man wäre besser dran mit einem caching-Muster für deinen look-up-Daten. Die Antworten auf diese caching-Frage bieten einige alternativen, um Ihre eigenen Rollen, obwohl Sie etwas veraltet.
Auch, wenn Sie sich entscheiden, dass macht das ganze service-Instanz eines singleton (InstanceContextMode=Einzeln) ist die einfachste Lösung, sich bewusst sein, dass Sie werden in der Regel töten, service-Skalierbarkeit, es sei denn, Sie machen auch Ihren code multithreaded (ConcurrencyMode=Mehrere). Wenn Sie knock-out-thread-sicheren code in Ihrem Schlaf dann ein singleton-service könnte für Sie sein.
einfachsten ist die Verwendung eines Synchronisationsmechanismus - haben Sie schaute auf lock(...) - diese wird als ein gatekeeper viel wie ein Kritischer Abschnitt (wenn Sie kommen über die in der windows-Programmierung)
definieren ein statisches Objekt in der Klasse
d.h.
Verwendung in der Methode erstellen
d.h.