Skip to content

Commit b6b314a

Browse files
author
Oren (electricessence)
committed
Added Recycler.
1 parent c57f796 commit b6b314a

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

source/Open.Disposable.ObjectPools.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ Part of the "Open" set of libraries.</Description>
1616
<RepositoryType>git</RepositoryType>
1717
<PackageTags>objectpool, dotnet, dotnetcore, cs, idisposable, threadsafe, thread-safe</PackageTags>
1818
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
19-
<Version>1.0.2</Version>
19+
<Version>1.0.3</Version>
2020
<AssemblyVersion>1.1.0.0</AssemblyVersion>
2121
<FileVersion>1.1.0.0</FileVersion>
22-
<PackageReleaseNotes>Wired up missing GiveAsync logic that would include recycling and giving to 'pocket'.</PackageReleaseNotes>
22+
<PackageReleaseNotes>Added a Recycler class to allow for 'queuing' a recycle process instead of piling up tasks.</PackageReleaseNotes>
2323
</PropertyGroup>
2424

2525
<ItemGroup>

source/Recycler.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using System.Threading.Tasks.Dataflow;
4+
5+
namespace Open.Disposable
6+
{
7+
/// <summary>
8+
/// This class is provided as an asynchronous queue for recycling instead of using a recycle delegate with an object pool and calling GiveAsync() which could pile up unnecessarily.
9+
/// So if recycling an object takes extra time, this might be a good way to toss objects away and not have to worry about the heavy cost as they will one by one be processed back into the target pool.
10+
/// </summary>
11+
public class Recycler<T> : DisposableBase
12+
where T : class
13+
{
14+
IObjectPool<T> _target;
15+
ActionBlock<T> _bin;
16+
17+
public Recycler(
18+
IObjectPool<T> target,
19+
Action<T> recycleFunction,
20+
ushort limit = ushort.MaxValue)
21+
{
22+
if(recycleFunction==null) throw new ArgumentNullException("recycleFunction");
23+
_target = target ?? throw new ArgumentNullException("target");
24+
25+
_bin = new ActionBlock<T>(item =>
26+
{
27+
if (_target != null)
28+
{
29+
recycleFunction(item);
30+
_target?.Give(item);
31+
}
32+
});
33+
34+
if (target is DisposableBase d)
35+
d.BeforeDispose += Pool_BeforeDispose;
36+
}
37+
38+
public Recycler(
39+
ushort limit,
40+
IObjectPool<T> pool,
41+
Action<T> recycleFunction) : this(pool, recycleFunction, limit)
42+
{
43+
44+
}
45+
46+
void Pool_BeforeDispose(object sender, EventArgs e)
47+
{
48+
Dispose();
49+
}
50+
51+
public bool Recycle(T item)
52+
{
53+
return _bin?.Post(item) ?? false;
54+
}
55+
56+
public Task Close()
57+
{
58+
var b = _bin;
59+
if (b == null) return Task.CompletedTask;
60+
b.Complete();
61+
return b.Completion;
62+
}
63+
64+
protected override void OnDispose(bool calledExplicitly)
65+
{
66+
_bin.Complete();
67+
_bin = null;
68+
_target = null;
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)