是否有在 .net 中实现专有连接池的标准方法? [英] Is there a standard way of implementing a proprietary connection pool in .net?

查看:22
本文介绍了是否有在 .net 中实现专有连接池的标准方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一个标准连接池模型(或 API)类似于 .net 中的数据提供者 使用的模型,我可以用它来实现我自己的连接池?

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?

我之所以这么问是因为我需要实现我自己的连接池到我们在 Web 服务中使用的专有 TCP/IP 设备.当前的问题是,由于在 IIS 下运行的 Web 服务的线程特性,有很多连接(读取太多)到设备.我想使用我自己的连接池来限制这些连接的数量,如果有一个标准模型可以用来做到这一点,重新发明轮子似乎很愚蠢.

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

除了 ADO.NET,没有.但是 ADO.NET 模型很好很简单.构造一个对象从池中获取连接,或重新创建,并在 Close/Dispose/Finalise 时返回到池中.

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.

类似于:

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

}

这不适用于 MyObject 被销毁的情况.例如.持有对分配的 MyObject 的弱引用的集合,如果池为空,则检查已处理的实例.如果您不能依赖客户端关闭或处理实例,或在 MyObjectImpl1 上实现终结器(并在调试版本中将此报告为错误),则也需要这样做.

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 MyObjectImpl1 (and report this as an error in debug builds).

1 这不能在 MyObject 上完成,因为在 MyObject 完成时 MyObjectImpl 实例可能已经完成了.

1 This cannot be done on MyObject because by the time MyObject was finalised the MyObjectImpl instance could already have been finalised.

这篇关于是否有在 .net 中实现专有连接池的标准方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆