Когда возвращать объект обратно в его пул

Я хочу использовать объектный пул в моем приложении C#, и я знаю, что в C# нет подсчета ссылок. Если один и тот же объект может быть передан нескольким потокам, как я могу узнать, когда больше нет ссылок на объект, чтобы я мог вернуть его в пул объектов?

Я думал сделать это в dispose метод, но это слишком поздно, и его нельзя вернуть в пул, поскольку он удаляется.

3 ответа

Решение

Реализация объектного пула в.Net может быть выполнена с помощью Finalizer.

На самом деле, большинство пулов, реализованных в.Net, также делают это (например, пул соединений с БД).

Использование финализатора позволяет вам узнать, что на объект больше не ссылаются, так как финализатор вызывается после того, как GC определит, что нет возможных маршрутов к объекту.

Техника не в том, чтобы делать какие-либо разрушительные методы в вашем Dispose (я получу это дальше) и завершить метод.

Допустим, у вас есть тип PooledObject и тип ObjectPool, который управляет пулом.

В ObjectPool добавьте внутренние методы с именем ReturnToPool(PooledObject obj), которые получат объект и сделают его доступным для других вызывающих.

В тип PooledObject вы должны добавить внутренний метод с именем ReleaseResources - который будет вызываться ObjectPool только тогда, когда весь пул должен быть удален из памяти - в этом методе вы реализуете логику удаления (закрывающие дескрипторы, освобождая неуправляемую память)., так далее..). В методах PooledObject Dispose и Finalize вы должны вызывать методы ReturnToPool в ObjectPool (статические или внутренне хранящиеся в объединенном объекте) - это называется - воскресение. При вызове метода ReturnToPool в финализаторе вы фактически воскрешаете объект и снова делаете его доступным.

Убедитесь, что вы перерегистрируете PooledObject для финализации в методе ReturnToPool в методе ObjectPool - GC.ReRegisterForFinalize.

Конечно, оба этих типа должны быть в одной сборке. (чтобы они могли вызывать внутренние методы друг друга)

Однако вы должны реализовать шаблон Dispose в любом случае. Это сэкономит время, когда объект больше не используется (например, после выхода из области применения) и вернет объект в пул.

Надеюсь это поможет. Офир.

как я могу узнать, когда больше нет ссылок на объект, чтобы я мог вернуть его в пул объектов.

Гектометр Вы осуществляете подсчет ссылок.

Что также работает, так это прокси-сервер, который имеет метод Disposable. После завершения работы с прокси реализация dispose помещает внутренний объект в пул (внешний объект очень маленький).

Но в конце вы должны знать, когда выпустить. Это называется программированием. Это имеет смысл только для "толстых" объектов со значительными издержками инициализации, и тогда вам действительно нужно убедиться, что вы точно знаете, когда вернуть их обратно с помощью логики (т. Е. Пользовательского счета и т. Д.).

Должно быть в Close / Release метод. Ответственность за создание и удаление экземпляра лежит на самом ObjectPool.

Чтобы запросить / освободить объект из / в ObjectPool, используйте Open / Close или же Acquire / Release,

В статье Code Project, C# Object Pooling, представлена ​​хорошая легкая реализация пользовательского пула объектов.

Вы также можете взглянуть на механизм пула соединений ADO.NET, чтобы получить подсказку о примере пула объектов.

Другие вопросы по тегам