Существует ли стандартная модель пула подключений
Кроме ADO.NET, нет. Но модель ADO.NET довольно проста. Создайте объект для получения соединения из пула или создания заново, и он возвращается в пул при закрытии / удалении / финализации.
Из этого можно сразу определить шаблон реализации:
- Тип клиента является прокси для реального типа и имеет время жизни от создания до
Закрыть / & hellip ;. Это прокси для реального объекта. Предоставляет методы и свойства, которые
жду реального соединения.
- Реальное соединение - это долгоживущий экземпляр, созданный пулом, выданным через прокси
а затем вернулся в конце прокси.
В реализации есть выбор. Когда объект был выдан, должен ли пул также сохранять ссылку? Если это так, пул должен отслеживать, какие объекты активны, а какие объединены; в противном случае можно использовать простой набор доступных объектов.
Что-то вроде:
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 уже мог быть завершен.