# object-pool **Repository Path**: abccc123/object-pool ## Basic Information - **Project Name**: object-pool - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-09 - **Last Updated**: 2024-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Object Pool [![License: MIT][project-license-badge]][project-license] [![Donate][paypal-donations-badge]][paypal-donations] [![standard-readme compliant][github-standard-readme-badge]][github-standard-readme] [![Docs][doxygen-docs-badge]][doxygen-docs] [![Gitlab pipeline status][gitlab-pipeline-status-badge]][gitlab-pipelines] [![NuGet version][nuget-version-badge]][nuget-package] [![NuGet downloads][nuget-downloads-badge]][nuget-package] [![Renovate enabled][renovate-badge]][renovate-website] A generic, concurrent, portable and flexible Object Pool for the .NET Framework, completely based on the [Code Project article of Ofir Makmal][code-project-article]. **Library is feature complete and no further development is planned on this project, except for routine maintenance and bug fixes.** Original source code has been modified, in order to introduce: - A Parameterized Object Pool, already drafted by Ofir Makmal in the comments of the article. - A Timed Object Pool, where objects are automatically removed after a period of inactivity. - Memory Stream and String Builder pools. - For use cases which might involve very large memory streams, I suggest to use the [`Microsoft.IO.RecyclableMemoryStream`][github-recyclable-memory-stream] library from Microsoft. It eliminates Large Object Heap allocations, which this library does not do. Moreover, a few unit tests have been added, in order to improve code reliability, and a lot of other small changes have also been applied. Of course, all modified source code is freely available in this repository. Many thanks to Ofir Makmal for his great work. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Async support](#async-support) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install NuGet package [CodeProject.ObjectPool][nuget-package] is available for download: ```bash dotnet add package CodeProject.ObjectPool ``` [An adapter for `Microsoft.Extensions.ObjectPool`][nuget-package-ms-adapter] is also available on NuGet: ```bash dotnet add package CodeProject.ObjectPool.MicrosoftExtensionsAdapter ``` ## Usage Quick and dirty example: ```cs /// /// Example usages of ObjectPool. /// internal static class Program { /// /// Example usages of ObjectPool. /// private static void Main() { // Creating a pool with a maximum size of 25, using custom Factory method to create and // instance of ExpensiveResource. var pool = new ObjectPool(25, () => new ExpensiveResource(/* resource specific initialization */)); using (var resource = pool.GetObject()) { // Using the resource... resource.DoStuff(); } // Exiting the using scope will return the object back to the pool. // Creating a pool with wrapper object for managing external resources, that is, classes // which cannot inherit from PooledObject. var newPool = new ObjectPool>(() => new PooledObjectWrapper(CreateNewResource()) { OnReleaseResources = ExternalResourceReleaseResource, OnResetState = ExternalResourceResetState }); using (var wrapper = newPool.GetObject()) { // wrapper.InternalResource contains the object that you pooled. wrapper.InternalResource.DoOtherStuff(); } // Exiting the using scope will return the object back to the pool. // Creates a pool where objects which have not been used for over 2 seconds will be // cleaned up by a dedicated thread. var timedPool = new TimedObjectPool(TimeSpan.FromSeconds(2)); using (var resource = timedPool.GetObject()) { // Using the resource... resource.DoStuff(); } // Exiting the using scope will return the object back to the pool and record last usage. Console.WriteLine($"Timed pool size after 0 seconds: {timedPool.ObjectsInPoolCount}"); // Should be 1 Thread.Sleep(TimeSpan.FromSeconds(4)); Console.WriteLine($"Timed pool size after 4 seconds: {timedPool.ObjectsInPoolCount}"); // Should be 0 // Adapts a timed pool to Microsoft Extensions abstraction. var mPool = ObjectPoolAdapter.CreateForPooledObject(timedPool); // Sample usage of Microsoft pool. var mResource = mPool.Get(); Debug.Assert(mResource is ExpensiveResource); mPool.Return(mResource); // Adapts a new pool to Microsoft Extensions abstraction. This example shows how to adapt // when object type does not extend PooledObject. var mPool2 = ObjectPoolAdapter.Create(new ObjectPool>( () => PooledObjectWrapper.Create(new MemoryStream()))); // Sample usage of second Microsoft pool. var mResource2 = mPool2.Get(); Debug.Assert(mResource2 is MemoryStream); mPool2.Return(mResource2); Console.Read(); } private static ExternalExpensiveResource CreateNewResource() { return new ExternalExpensiveResource(); } public static void ExternalResourceResetState(ExternalExpensiveResource resource) { // External Resource reset state code. } public static void ExternalResourceReleaseResource(ExternalExpensiveResource resource) { // External Resource release code. } } internal sealed class ExpensiveResource : PooledObject { public ExpensiveResource() { OnReleaseResources = () => { // Called if the resource needs to be manually cleaned before the memory is reclaimed. }; OnResetState = () => { // Called if the resource needs resetting before it is getting back into the pool. }; } public void DoStuff() { // Do some work here, for example. } } internal sealed class ExternalExpensiveResource { public void DoOtherStuff() { // Do some work here, for example. } } ``` ### Async support Starting from v4, Object Pool supports async pooled object initialization. Therefore, objects can be retrieved in two ways: ```cs obj = pool.GetObject(); obj = await pool.GetObjectAsync(); ``` Those methods depend on the factory method specified during pool initialization. Because making async factories "sync" is usually a problem, which can lead to deadlocks, we have the following situation: | Factory type | `GetObject` | `GeObjectAsync` | | ------------- | --------------------------- | ---------------------- | | Not specified | OK | OK, uses a result task | | Sync | OK | OK, uses a result task | | Async | **KO**, throws an exception | OK | So, to sum it up: - If a sync factory is specified, both retrieval methods can be used. - If an async factory is specified, only the async retrieval can be used. ## Maintainers [@pomma89][gitlab-pomma89]. ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme][github-standard-readme] specification. ## License MIT © 2013-2021 [Alessio Parma][personal-website] [code-project-article]: https://www.codeproject.com/Articles/535735/Implementing-a-Generic-Object-Pool-in-NET [doxygen-docs]: https://pomma89.gitlab.io/object-pool/ [doxygen-docs-badge]: https://img.shields.io/badge/Doxygen-OK-green?style=flat-square [github-recyclable-memory-stream]: https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream [github-standard-readme]: https://github.com/RichardLitt/standard-readme [github-standard-readme-badge]: https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square [gitlab-pipeline-status-badge]: https://gitlab.com/pomma89/object-pool/badges/main/pipeline.svg?style=flat-square [gitlab-pipelines]: https://gitlab.com/pomma89/object-pool/pipelines [gitlab-pomma89]: https://gitlab.com/pomma89 [nuget-downloads-badge]: https://img.shields.io/nuget/dt/CodeProject.ObjectPool?style=flat-square [nuget-package]: https://www.nuget.org/packages/CodeProject.ObjectPool/ [nuget-package-ms-adapter]: https://www.nuget.org/packages/CodeProject.ObjectPool.MicrosoftExtensionsAdapter/ [nuget-version-badge]: https://img.shields.io/nuget/v/CodeProject.ObjectPool?style=flat-square [paypal-donations]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ELJWKEYS9QGKA [paypal-donations-badge]: https://img.shields.io/badge/Donate-PayPal-important.svg?style=flat-square [personal-website]: https://alessioparma.xyz/ [project-license]: https://gitlab.com/pomma89/object-pool/-/blob/main/LICENSE [project-license-badge]: https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square [renovate-badge]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square [renovate-website]: https://renovate.whitesourcesoftware.com/