5 Stimmen

Gibt es eine Standardmethode zur Implementierung eines proprietären Verbindungspools in .net?

Gibt es eine Standardmodell für das Pooling von Verbindungen (oder API), ähnlich dem, das von der datenanbieter in .net die ich verwenden könnte, um meinen eigenen Verbindungspool zu implementieren?

Ich frage, weil ich einen eigenen Verbindungspool für ein proprietäres TCP/IP-Gerät implementieren muss, das wir in einem Webdienst verwenden. Das derzeitige Problem besteht darin, dass es viele Verbindungen (zu viele) zu dem Gerät gibt, da die Webdienste unter IIS mit Threads laufen. Ich möchte die Anzahl dieser Verbindungen mit meinem eigenen Verbindungspool begrenzen, und es erscheint mir dumm, das Rad neu zu erfinden, wenn es ein Standardmodell gibt, das ich dafür verwenden könnte.

0 Stimmen

Welche .NET-APIs verwenden Sie für die Kommunikation mit dem Gerät? Sockets? TCPClient?

0 Stimmen

Ich verwende die Klasse TCPClient.

6voto

Richard Punkte 103159

Gibt es ein Standardmodell für das Pooling von Verbindungen?

Anders als ADO.NET, nein. Aber das ADO.NET-Modell ist schön und einfach. Konstruieren Sie ein Objekt, um eine Verbindung aus dem Pool zu erhalten, oder erstellen Sie es neu, und es wird bei Close/Dispose/Finalise an den Pool zurückgegeben.

Daraus kann man sofort ein Implementierungsmuster ableiten:

  • Der Client-Typ ist ein Proxy für den echten Typ und hat eine Lebensdauer von der Erstellung bis Schließen/ . Er ist ein Proxy für das echte Objekt. Bietet Methoden und Eigenschaften, die an die echte Verbindung weiterleiten.
  • Die echte Verbindung ist eine langlebige Instanz, die vom Pool erstellt und über einen Proxy weitergegeben wird ausgegeben und am Ende des Proxys zurückgegeben wird.

Bei der Umsetzung gibt es eine Auswahlmöglichkeit. Muss der Pool auch eine Referenz behalten, wenn ein Objekt weitergegeben wurde? Wenn ja, muss der Pool verfolgen, welche Objekte aktiv sind und welche gepoolt werden; andernfalls kann eine einfache Sammlung der verfügbaren Objekte verwendet werden.

Etwa so:

internal class MyObjectImpl {
  // The real object that holds the resource
}

internal static class MyObjectPool {
  private static object syncRoot = new object();
  private static Queue<MyObjectImpl> pool = new Queue<MyObject>();
  private static int totalObjects = 0;
  private readonly int maxObjects = 10;

  internal MyObjectImplGet() {
    lock (syncRoot) {
      if (pool.Count > 0) {
        return pool.Dequeue();
      }
      if (totalObjects >= maxObjects) {
        throw new PoolException("No objects available");
      }
      var o = new MyObjectImpl();
      totalObjects++;
      return o;
    }
  }

  internal void Return(MyObjectImpl obj) {
    lock (syncRoot) {
      pool.Enqueue(obj);
    }
  }
}

public class MyObject : IDisposable {
  private MyObjectImpl impl;

  public MyObject() {
    impl = MyObjectPool.Get();
  }

  public void Close() {
    Dispose();
  }

  public void Dispose() {
    MyIObjectPool.Return(impl);
    // Prevent continuing use, as the implementation object instance
    // could now be given out.
    impl = null;
  }

  // Forward API to implement

}

Dies gilt nicht für Fälle, in denen MyObject zerstört werden. Z.B. eine Sammlung von schwachen Referenzen auf zugewiesene MyObject und wenn der Pool leer ist, wird nach entsorgten Instanzen gesucht. Dies wird auch benötigt, wenn man sich nicht auf Client's verlassen kann, um Instanzen zu schließen oder zu entsorgen, oder einen Finalisierer auf MyObjectImpl 1 (und melden dies als Fehler in Debug-Builds).

1 Dies ist bei MyObject nicht möglich, da zu dem Zeitpunkt, zu dem MyObject finalisiert wurde, die Instanz MyObjectImpl bereits finalisiert worden sein könnte.

4voto

Neil Barnwell Punkte 39692

Update

Jetzt, da ich mehr weiß, würde ich wohl eine Funktion aus meinem IoC-Container der Wahl - Schloss Windsor . Eine der eingebauten Lebensstile ist " gepoolt "Das heißt, wenn Sie den Container nach einem Objekt fragen, das mit diesem Lebensstil registriert wurde, wird er Ihnen eines der gepoolten Objekte geben, wenn er kann, oder ein neues erstellen.

Zuvor...

Ich denke, Sie wollen "Objekt-Pooling" implementieren. Hier sind ein paar Dinge, die vielversprechend aussahen:

Natürlich müssen Sie bei Ihren gepoolten Objekten auf die Gleichzeitigkeit und die Synchronisierung von Threads usw. achten.


Für Datenbankverbindungen:

Sie können die Anzahl der Verbindungen im .NET-Verbindungspool mit einer Option in der Verbindungszeichenfolge steuern: "max pool size" wie beschrieben in: http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx

Versuchen Sie nach Möglichkeit, die Einführung eines eigenen Systems zu vermeiden.

0voto

MusiGenesis Punkte 72729

Web-Service-Methoden sollen zustandslos sein (d.h. zwischen den Aufrufen werden keine Objekte auf dem Server aufrechterhalten). Was Sie tun wollen, ist eine Sammlung von proprietären Verbindungsobjekten auf dem Server zwischen den Aufrufen aufrechtzuerhalten und bestehende Verbindungsobjekte aus diesem Pool jedem Methodenaufruf zuzuweisen (anstatt ein neues Verbindungsobjekt in jeder Methode zu erstellen).

Eine einfache Möglichkeit, dies zu tun, besteht darin, Ihre Sammlung von Objekten als "private static" innerhalb des Anwendungsbereichs Ihres Webdienstes, aber außerhalb des Anwendungsbereichs jeder Methode zu deklarieren, etwa so:

public class Service1 : System.Web.Services.WebService
{
    private static List<CustomConnection> _connections = 
        new List<CustomConnection>();

    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

und füllen Sie dann die Sammlung aus dem Startup-Ereignis des Webdienstes auf (ich weiß im Moment nicht mehr, welches Ereignis das ist - ich werde es gleich nachreichen). Jede Methode, die eine Verbindung verwenden muss, holt sich ein Verbindungsobjekt aus dieser Liste, anstatt eine neue zu erstellen (Sie müssen sich um die Zuweisung von Verbindungen kümmern und sie als "in Gebrauch" markieren usw.).

Dies funktioniert gut, wenn Ihr Webdienst häufig aufgerufen wird (Webdienste werden in der Regel nach 20 Minuten Inaktivität abgeschaltet, so dass der Verbindungspool für den nächsten Aufruf neu aufgebaut werden muss). Wenn Sie Ihre Sammlung von Verbindungen darüber hinaus aufrechterhalten müssen, lesen Sie diesen Artikel:

http://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X