是否有标准连接池模型(或API)类似于.net 中的数据提供程序所使用的模型,我可以使用它来实现我自己的连接池?
我问,因为我需要将我自己的连接池实现到我们在Web服务中使用的专用TCP / IP设备。目前的问题是,由于在IIS下运行的Web服务的线程特性,设备有很多连接(读取太多)。我想使用我自己的连接池来限制这些连接的数量,如果有一个我可以使用的标准模型,重新发明轮子似乎很愚蠢。
答案 0 :(得分:6)
是否存在标准连接池模型
除了ADO.NET,没有。但是ADO.NET模型很简单。构造一个对象以从池中获取连接,或者重新创建一个对象,并在Close / Dispose / Finalize上将其返回到池中。
从这个可以立即确定一个实现模式:
实施中有一个选择。当一个对象被分发时,池是否还需要保留引用?如果它确实需要跟踪哪些对象是活动的以及哪些对象是合并的;否则可以使用简单的可用对象集合。
类似的东西:
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 (totalOjects >= 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 imp
}
这不适合MyObject
被摧毁的情况。例如。保存对已分配的MyObject
的弱引用的集合,如果池为空,则检查已处置的实例。如果您不能依赖客户端来关闭或处理实例,或者在MyObjectImpl
1 上实现终结器(并在调试版本中将其报告为错误),那么也需要这样做。
1 这不能在MyObject上完成,因为在MyObject完成时,MyObjectImpl实例可能已经完成。
答案 1 :(得分:4)
实际上现在我知道更多,我想我会使用我选择的IoC container中的一项功能 - Castle Windsor。其中一个内置的lifestyles是“pooled”,这意味着每当你向容器询问一个以这种生活方式注册的对象时,它会给你一个合并的对象,如果它可以,或者创建一个新的。
我认为你想实现“对象池”。以下是一些看起来很有希望的事情:
当然,对于您的池化对象,您需要注意并发和线程同步等。
对于数据库连接:
您可以使用连接字符串中的选项控制.NET连接池中的连接数:“max pool size”,如下所述:http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.71).aspx
如果可以的话,尽量避免实施自己的。
答案 2 :(得分:0)
Web服务方法意味着无状态(即在调用之间服务器上不存在任何对象)。您要做的是在调用之间维护服务器上的专有连接对象的集合,并将此池中的现有连接对象分配给每个方法调用(而不是在每个方法中创建新的连接对象)。
执行此操作的一种简单方法是将您的对象集合声明为Web服务范围内的“私有静态”,但不在任何方法的范围内,如下所示:
public class Service1 : System.Web.Services.WebService
{
private static List<CustomConnection> _connections =
new List<CustomConnection>();
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
然后从Web服务的启动事件中填充集合(我不记得此刻发生的事件 - 我将在一秒钟内回复它)。任何需要使用连接的方法都会从此列表中获取连接对象,而不是创建新的连接对象(您必须处理分配连接并将其标记为“正在使用”等方法)。
如果经常调用您的Web服务,这将正常工作(Web服务通常在20分钟不活动后关闭,这将需要重建连接池以进行下一次调用)。如果您需要维护超出此范围的连接集合,请查看以下文章:
http://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx