Skip to content

Commit 6063fb9

Browse files
author
electricessence
committed
Merge
2 parents 02714c7 + c33353b commit 6063fb9

3 files changed

Lines changed: 87 additions & 84 deletions

File tree

source/Collection/ConcurrentQueueObjectPool.cs

Lines changed: 83 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -3,87 +3,87 @@
33

44
namespace Open.Disposable
55
{
6-
public sealed class ConcurrentQueueObjectPool<T> : TrimmableObjectPoolBase<T>
7-
where T : class
8-
{
9-
10-
public ConcurrentQueueObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
11-
: base(factory, recycler, capacity)
12-
{
13-
Pool = new ConcurrentQueue<T>();
14-
}
15-
16-
public ConcurrentQueueObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
17-
: this(factory, null, capacity)
18-
{
19-
20-
}
21-
22-
ConcurrentQueue<T> Pool;
23-
24-
public override int Count => Pool?.Count ?? 0;
25-
26-
// For ConcurrentQueue disable using the Pocket. It's fast enough as it is...
27-
protected override bool SaveToPocket(T item)
28-
{
29-
return false;
30-
}
31-
32-
protected override T TakeFromPocket()
33-
{
34-
return null;
35-
}
36-
37-
protected override bool Receive(T item)
38-
{
39-
var p = Pool;
40-
if (p == null) return false;
41-
p.Enqueue(item); // It's possible that the count could exceed MaxSize here, but the risk is negligble as a few over the limit won't hurt.
42-
return true;
43-
}
44-
45-
protected override T TryRelease()
46-
{
47-
var p = Pool;
48-
if (p == null) return null;
49-
p.TryDequeue(out T item);
50-
return item;
51-
}
52-
53-
protected override void OnDispose(bool calledExplicitly)
54-
{
55-
Pool = null;
56-
}
57-
58-
}
59-
60-
public static class ConcurrentQueueObjectPool
61-
{
62-
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
63-
where T : class
64-
{
65-
return new ConcurrentQueueObjectPool<T>(factory, capacity);
66-
}
67-
68-
69-
public static ConcurrentQueueObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
70-
where T : class, new()
71-
{
72-
return Create(() => new T(), capacity);
73-
}
74-
75-
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
76-
where T : class, IRecyclable
77-
{
78-
Action<T> recycler = null;
79-
if (autoRecycle) recycler = Recycler.Recycle;
80-
return new ConcurrentQueueObjectPool<T>(factory, recycler, capacity);
81-
}
82-
83-
public static ConcurrentQueueObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
84-
where T : class, IRecyclable, new()
85-
{
86-
return Create(() => new T(), autoRecycle, capacity);
87-
}
88-
}
6+
public sealed class ConcurrentQueueObjectPool<T> : TrimmableObjectPoolBase<T>
7+
where T : class
8+
{
9+
10+
public ConcurrentQueueObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
11+
: base(factory, recycler, capacity)
12+
{
13+
Pool = new ConcurrentQueue<T>();
14+
}
15+
16+
public ConcurrentQueueObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
17+
: this(factory, null, capacity)
18+
{
19+
20+
}
21+
22+
ConcurrentQueue<T> Pool;
23+
24+
public override int Count => Pool?.Count ?? 0;
25+
26+
// For ConcurrentQueue disable using the Pocket. It's fast enough as it is...
27+
protected override bool SaveToPocket(T item)
28+
{
29+
return false;
30+
}
31+
32+
protected override T TakeFromPocket()
33+
{
34+
return null;
35+
}
36+
37+
protected override bool Receive(T item)
38+
{
39+
var p = Pool;
40+
if (p == null) return false;
41+
p.Enqueue(item); // It's possible that the count could exceed MaxSize here, but the risk is negligble as a few over the limit won't hurt.
42+
return true;
43+
}
44+
45+
protected override T TryRelease()
46+
{
47+
var p = Pool;
48+
if (p == null) return null;
49+
p.TryDequeue(out T item);
50+
return item;
51+
}
52+
53+
protected override void OnDispose(bool calledExplicitly)
54+
{
55+
Pool = null;
56+
}
57+
58+
}
59+
60+
public static class ConcurrentQueueObjectPool
61+
{
62+
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
63+
where T : class
64+
{
65+
return new ConcurrentQueueObjectPool<T>(factory, capacity);
66+
}
67+
68+
69+
public static ConcurrentQueueObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
70+
where T : class, new()
71+
{
72+
return Create(() => new T(), capacity);
73+
}
74+
75+
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
76+
where T : class, IRecyclable
77+
{
78+
Action<T> recycler = null;
79+
if (autoRecycle) recycler = Recycler.Recycle;
80+
return new ConcurrentQueueObjectPool<T>(factory, recycler, capacity);
81+
}
82+
83+
public static ConcurrentQueueObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
84+
where T : class, IRecyclable, new()
85+
{
86+
return Create(() => new T(), autoRecycle, capacity);
87+
}
88+
}
8989
}

source/ObjectPoolBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public Task GiveAsync(T item)
9393
async Task ReceiveConditionalAsync(T item)
9494
{
9595
if(PrepareToReceive(item)
96-
&& (SaveToPocket(item) || await ReceiveAsync(item)))
96+
&& (SaveToPocket(item) || await ReceiveAsync(item).ConfigureAwait(false))) // Doesn't need original context. Just needs to trigger OnReceived().
9797
OnReceived();
9898
}
9999
#endregion

source/Recycler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ public class Recycler<T> : DisposableBase
1212
where T : class
1313
{
1414
IObjectPool<T> _target;
15+
16+
// Something else could be used and could be more performant.
17+
// But it's an ideal interface for what's needed. And the point is that the recyler should not take up too much cpu time.
1518
ActionBlock<T> _bin;
1619

1720
internal Recycler(

0 commit comments

Comments
 (0)