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.
0 Stimmen
Welche .NET-APIs verwenden Sie für die Kommunikation mit dem Gerät? Sockets? TCPClient?
0 Stimmen
Ich verwende die Klasse TCPClient.