# 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/