连接池:如何正确实现IDisposable以将TCP连接返回到池

本文关键字:连接 TCP 以将 返回 实现 何正确 IDisposable | 更新日期: 2023-09-27 18:29:48

我正在尝试实现TCP连接池,并使用IDisposable将连接返回到池。我想知道我的实现是否正确,它似乎正在工作,但我认为,因为基类也实现了IDisposable和finalize,所以我的代码可能会泄漏。

 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);
        }
    }
}

您可以在程序中这样使用它:

 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

连接池:如何正确实现IDisposable以将TCP连接返回到池

MyClass不应该定义新的Dispose(),因为它确实会导致资源泄漏(如果它不调用base.Dispose())。

相反,您可以使用另一个类:

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;
    }
}

这是SO上关于实现IDisposable 的一篇很棒的文章