Skip to content

Instantly share code, notes, and snippets.

@CleanCoder
Created July 20, 2018 02:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CleanCoder/b098cf7da79a10cb3b9efeb4b7737a44 to your computer and use it in GitHub Desktop.
Save CleanCoder/b098cf7da79a10cb3b9efeb4b7737a44 to your computer and use it in GitHub Desktop.
Object Pool
public class ObjectPoolAsync<T> : IDisposable
{
private readonly BufferBlock<T> buffer;
private readonly Func<T> factory;
private readonly int msecTimeout;
public ObjectPoolAsync (int initialCount, Func<T> factory, CancellationToken cts, int msecTimeout = 0)
{
this.msecTimeout = msecTimeout;
buffer = new BufferBlock<T> ( new DataflowBlockOptions { CancellationToken = cts });
this.factory = () => factory ();
for (int i = 0; i < initialCount; i++)
buffer.Post (this.factory ());
}
public Task<bool> PutAsync (T item) => buffer.SendAsync (item);
public Task<T> GetAsync (int timeout = 0)
{
var tcs = new TaskCompletionSource<T> ();
buffer.ReceiveAsync (TimeSpan.FromMilliseconds (msecTimeout))
.ContinueWith (task =>
{
if (task.IsFaulted)
if (task.Exception.InnerException is TimeoutException)
tcs.SetResult (factory ());
else
tcs.SetException (task.Exception);
else if (task.IsCanceled)
tcs.SetCanceled ();
else
tcs.SetResult (task.Result);
});
return tcs.Task;
}
public void Dispose () => buffer.Complete ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment