Is there a standard connection pooling model (or API) similar to that used by the data providers in .net that I could use to implement my own connection pool?
I ask because I have a requirement to implement my own connection pool to a proprietary TCP/IP device that we use in a web service. The current problem is that there are lot of connections (read too many) to the device due to the threaded nature of web services running under IIS. I want to limit the number of these connections using my own connection pool and it seems stupid to reinvent the wheel if there is a standard model I could use to do this.
Is there a standard connection pooling model
Other than ADO.NET, no. But the ADO.NET model is nice an simple. Construct an object to get a connection from the pool, or created anew, and it is returned to the pool on Close/Dispose/Finalise.
From this one can immediately determine an implementation pattern:
There is a choice in the implementation. When an object has been handed out, does the pool need to also keep a reference? If it does the pool needs to track which objects are active and which are pooled; otherwise a simple collection of available objects can be used.
Something like:
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
}
This doesn't cater for instances of MyObject
being destroyed. E.g. hold a collection of weak references to allocated MyObject
's, and if the pool is empty check for disposed instances. This would also be needed if you cannot rely on client's to Close or dispose of instances, or implement a finaliser on MyObjectImpl
1 (and report this as an error in debug builds).
1 This cannot be done on MyObject because by the time MyObject was finalised the MyObjectImpl instance could already have been finalised.
Actually now I know more, I think I'd use a feature from my IoC container of choice - Castle Windsor. One of the built-in lifestyles is "pooled", which means that whenever you ask the container for an object that was registered with this lifestyle, it'll give you one of the pooled objects if it can, or else create a new one.
I think you want to implement "object pooling". Here's a few things that looked promising:
Of course with your pooled objects, you need to be careful with concurrency and thread synchronisation etc.
For database connections:
You can control the number of connections in the .NET connection pool with an option in the connection string: "max pool size" as described in: http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx
Try to avoid implementing your own if you can.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With