2012-03-31 7 views
1

implementieren Ich versuche TCP-Verbindungspooling zu implementieren und eine Verbindung zurück zum Pool mit IDisposable. Ich frage mich, ob meine Implementierung korrekt ist, es scheint zu funktionieren, aber ich denke, weil die Basisklasse auch IDisposable implementiert und finalisiert, könnte mein Code undicht sein.Verbindungspooling: Wie IDisposable korrekt zu TCP-Verbindung zurück zu Pool

public class BaseClass : IDisposable 
{ 
    internal bool IsDisposed { get; set; } 
    private object someResource; 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    ~BaseClass() 
    { 
     Dispose(false); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (someResource != null) 
     { 
      // some clearn up 
      return; 
     } 

     if (disposing) 
     { 
      //dispose un managed resources 

     } 
    } 
} 

public class ChildClass : BaseClass 
{ 
    // adds some functionality 
} 

public class MyClass : ChildClass, IDisposable 
{ 
    MyPoolManager manager = null; 

    public MyClass(MyPoolManager manager) 
    { 
     this.manager = manager; 

    } 
    public new void Dispose() 
    { 
     manager.ReturnPooledConnection(this); 
    } 
} 

public class MyPoolManager 
{ 
    private static MyPoolManager instance = new MyPoolManager(); 
    private static object objLock = new object(); 

    private static Queue<MyClass> que = null; 
    private string name; 

    static MyPoolManager() 
    { 
     que = new Queue<MyClass>(); 
     // enqueue some instances of MyClass here 
     MyClass client = new MyClass(instance); 
     que.Enqueue(client); 
    } 

    private MyPoolManager() { } 

    public MyPoolManager(string name) 
    { 
     this.name = name; 
    } 


    public MyClass GetPooledConnection() 
    { 
     lock (objLock) 
     { 
      while (que.Count == 0) 
      { 
       if (!Monitor.Wait(objLock, 1000)) 
        throw new TimeoutException("Connection timeout"); 
      } 
      return que.Dequeue(); 
     } 
    } 

    public void ReturnPooledConnection(MyClass client) 
    { 
     lock (objLock) 
     { 
      que.Enqueue(client); 
      Monitor.Pulse(objLock); 
     } 
    } 
} 

Und Sie würden es so in Ihrem Programm verwenden:

MyPoolManager pool = new MyPoolManager(); 
using (var conn = pool.GetPooledConnection()) 
{ 
     // use the conn here 
} 

// when you reach here the conn should have returned back to the pool 
+3

Welche Art von Verbindung reden wir hier? –

+1

+1 @MaciejDopieralski Dies ist eine gute Frage, weil .NET bereits eine Datenbankverbindung Pooling-Mechanismus ... – surfen

+0

eine TCP-IP-Verbindung zu einem Remote-Server geöffnet hat. – newbie

Antwort

-1

MyClass nicht neu Dispose() definieren sollte, denn in der Tat kann es zu durchgesickert Ressourcen führen (wenn es doesn t rufen Sie base.Dispose()).

Stattdessen können Sie eine andere Klasse verwenden:

public class MyClassWrapper : IDisposable 
{ 
    MyPoolManager manager = null; 
    MyClass myClass = null; 

    public MyClassWrapper(MyPoolManager manager, MyClass myClass) 
    { 
     this.manager = manager; 
     this.myClass = myClass; 

    } 

    public void Dispose() 
    { 
     manager.ReturnPooledConnection(this.myClass); 
    } 

    public MyClass GetMyClass() 
    { 
     return this.myClass; 
    } 
} 

Here ist ein großer Beitrag auf SO über die Implementierung von IDisposable

+1

'Super' in C#? Super. –

+0

danke, ich reparierte es – surfen

+0

, wenn ich base.Dispose() anrufe, würde es dann nicht entsorgt werden? Ich möchte nur, dass das Objekt in den Pool zurückkehrt, ich werde es wiederverwenden. – newbie

Verwandte Themen