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

时间:2012-03-31 23:31:07

标签: c# .net clr

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

 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

1 个答案:

答案 0 :(得分:-1)

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

Here是关于实施IDisposable

的SO文章