HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Generic Object Pool in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericobjectpool

Problem

I have a limit of 100 sessions (each session held in an object). Many threads will be requesting sessions, and it is very possible that all 100 sessions could be in use at any time.

I'm a Junior Developer. I saw the Object Pool pattern and decided that it looked appropriate. What do you think? If no sessions are avaible, the thread that requested it will get an Exception back and have to try again.

I'm using IOC with ISessionPool as a singleton. In testing it seems to work well, but I'd appreciate any feedback.

```
public class SessionPool : ISessionPool
{
private readonly List _inUse;
private readonly List _available;
private readonly Action _cleanerAction;

///
/// Creates an object pool for objects of type T.
/// NOTE: All availbale instances are initialised immediately.
///
/// A function that creates objects of type T
/// The maximum number of instances
/// An action that cleans up the object before it is returned to the pool
public SessionPool(Func instanceCreator, int maxInstances, Action cleanerAction)
{
_inUse = new List(maxInstances);
_available = new List(maxInstances);
_cleanerAction = cleanerAction;

CreateAllInstances(instanceCreator, maxInstances);
}

private void CreateAllInstances(Func instanceCreator, int numberOfInstances)
{
for (int i = 0; i < numberOfInstances; i++)
{
_available.Add(instanceCreator.Invoke());
}
}

public T GetSession()
{
lock (_available)
{
if (_available.Count == 0)
{
throw new NoAvailableSessionsException("Unable to get session");
}
else
{
T toReturn = _available[0];
_inUse.Add(toReturn);
_available.RemoveAt(0);
return toReturn;
}
}
}

public void ReleaseSession(T session)
{
// Clean up the o

Solution

A security problem is ReleaseSession adds whatever T session passed to _available, whether it was issued by you or not.

You can change _inUse like so:

HashSet _inUse = new HashSet(new ObjectReferenceEqualityComparer())


where ObjectReferenceEqualityComparer is an EqualityComparer that uses Object.ReferenceEquals and check whether _inUse contains session before adding it to the _available to avoid that problem.

You may think because you intend, for now, to use this pool with class X, which you think, for now, this problem does not apply. It may turn out that this problem applies to X after all, or someone else, or even yourself, may use this pool for some other class Y.

Code Snippets

HashSet _inUse = new HashSet<T>(new ObjectReferenceEqualityComparer<T>())

Context

StackExchange Code Review Q#69526, answer score: 4

Revisions (0)

No revisions yet.