Skip to content

Commit d066b15

Browse files
committed
fix: bug on create channel
1 parent 28b921a commit d066b15

2 files changed

Lines changed: 36 additions & 105 deletions

File tree

Pool/Pool.cs

Lines changed: 33 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public class Pool<T> : IPool<T> where T : class
1515
private readonly ConcurrentBag<T> _items;
1616
private readonly object _lock = new();
1717
private readonly Func<T> _factory;
18-
private readonly int _createIncrement;
1918
private readonly int _maxPoolSize;
2019
private int _currentSize;
2120
private bool _disposed;
@@ -28,17 +27,15 @@ public class Pool<T> : IPool<T> where T : class
2827
/// <param name="shrinkInterval">Time interval to shrink unused pools and disposed them, then reset to initPoolSize, default value is 30 min on null param</param>
2928
/// <param name="initPoolSize">The initial number of objects to be created and added to the pool. Default is 100.</param>
3029
/// <param name="maxPoolSize">The maximum number of objects that can be in the pool. Default is <see cref="int.MaxValue"/>.</param>
31-
/// <param name="createIncrement">When there is no object on pool, how many new item should create</param>
3230
/// <exception cref="ArgumentNullException">Thrown when <paramref name="factory"/> is null.</exception>
3331
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="initPoolSize"/> is negative or <paramref name="maxPoolSize"/> is less than or equal to zero.</exception>
3432
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="shrinkInterval"/> is less than 30 min (just if not null)</exception>
3533
/// <exception cref="ArgumentException">Thrown when <paramref name="maxPoolSize"/> is less than <paramref name="initPoolSize"/>.</exception>
36-
public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkInterval = null, int initPoolSize = 100, int maxPoolSize = int.MaxValue, int createIncrement = 1)
34+
public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkInterval = null, int initPoolSize = 100, int maxPoolSize = int.MaxValue)
3735
{
3836
#if NET8_0
3937
ArgumentNullException.ThrowIfNull(factory);
4038
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(initPoolSize);
41-
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(createIncrement);
4239
#else
4340
if (factory is null)
4441
{
@@ -49,11 +46,6 @@ public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkIn
4946
{
5047
throw new ArgumentOutOfRangeException(nameof(initPoolSize), Resources.Can_Not_Be_Zero);
5148
}
52-
53-
if (createIncrement < 1)
54-
{
55-
throw new ArgumentOutOfRangeException(nameof(createIncrement), Resources.Can_Not_Be_Zero);
56-
}
5749
#endif
5850

5951
if (maxPoolSize <= 0)
@@ -66,11 +58,6 @@ public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkIn
6658
throw new ArgumentOutOfRangeException(nameof(maxPoolSize), Resources.Max_Pool_Size_More_Than_Init);
6759
}
6860

69-
if (maxPoolSize < createIncrement)
70-
{
71-
throw new ArgumentOutOfRangeException(nameof(createIncrement), Resources.Max_Create_Increament);
72-
}
73-
7461
if (shrinkInterval != null && shrinkInterval < TimeSpan.FromMinutes(30))
7562
{
7663
throw new ArgumentOutOfRangeException(nameof(shrinkInterval), Resources.Min_Shrink_Interval);
@@ -80,7 +67,6 @@ public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkIn
8067
_factory = factory;
8168
_maxPoolSize = maxPoolSize;
8269
_currentSize = initPoolSize;
83-
_createIncrement = createIncrement;
8470
_semaphore = new SemaphoreSlim(maxPoolSize, maxPoolSize);
8571
_cleanupAction = cleanupAction ?? (item =>
8672
{
@@ -92,7 +78,7 @@ public Pool(Func<T> factory, Action<T>? cleanupAction = null, TimeSpan? shrinkIn
9278

9379
for (var i = 0; i < initPoolSize; i++)
9480
{
95-
Create();
81+
_items.Add(Create());
9682
}
9783

9884
#if NET8_0
@@ -116,30 +102,7 @@ public T GetFromPool()
116102

117103
try
118104
{
119-
_ = _items.TryTake(out var result);
120-
121-
if (result == null)
122-
{
123-
lock (_lock)
124-
{
125-
//Maybe another thread create item
126-
_ = _items.TryTake(out result);
127-
128-
if (result == null)
129-
{
130-
TryCreate(_createIncrement);
131-
_ = _items.TryTake(out result);
132-
}
133-
}
134-
}
135-
136-
if (result == null)
137-
{
138-
_ = _semaphore.Release();
139-
throw new InvalidOperationException(Resources.Failed_Create_Resource);
140-
}
141-
142-
return result;
105+
return _items.TryTake(out var result) ? result : TryCreate();
143106
}
144107
catch
145108
{
@@ -159,30 +122,7 @@ public async Task<T> GetFromPoolAsync()
159122

160123
try
161124
{
162-
_ = _items.TryTake(out var result);
163-
164-
if (result == null)
165-
{
166-
lock (_lock)
167-
{
168-
//Maybe another thread create item
169-
_ = _items.TryTake(out result);
170-
171-
if (result == null)
172-
{
173-
TryCreate(_createIncrement);
174-
_ = _items.TryTake(out result);
175-
}
176-
}
177-
}
178-
179-
if (result == null)
180-
{
181-
_ = _semaphore.Release();
182-
throw new InvalidOperationException(Resources.Failed_Create_Resource);
183-
}
184-
185-
return result;
125+
return _items.TryTake(out var result) ? result : TryCreate();
186126
}
187127
catch
188128
{
@@ -255,52 +195,41 @@ public void Dispose()
255195
/// <param name="disposing">A boolean value indicating whether the method is called from the Dispose method.</param>
256196
protected virtual void Dispose(bool disposing)
257197
{
258-
if (_disposed)
259-
{
260-
return;
261-
}
262-
263-
if (disposing)
198+
lock (_lock)
264199
{
265-
_semaphore.Dispose();
266-
_shrinkTimer.Dispose();
267-
268-
while (_items.TryTake(out var item))
200+
if (_disposed)
269201
{
270-
_cleanupAction(item);
202+
return;
271203
}
272-
}
273204

274-
_disposed = true;
275-
}
276-
277-
private void TryCreate(int count)
278-
{
279-
for (var i = 0; i < count; i++)
280-
{
281-
try
282-
{
283-
TryCreateSingle();
284-
}
285-
catch (InvalidOperationException)
205+
if (disposing)
286206
{
207+
_semaphore.Dispose();
208+
_shrinkTimer.Dispose();
209+
210+
while (_items.TryTake(out var item))
211+
{
212+
_cleanupAction(item);
213+
}
287214
}
215+
216+
_disposed = true;
288217
}
289218
}
290219

291-
private void TryCreateSingle()
220+
private T TryCreate()
292221
{
293-
var newSize = Interlocked.Increment(ref _currentSize);
294-
295-
if (newSize > _maxPoolSize)
296-
{
297-
_ = Interlocked.Decrement(ref _currentSize);
298-
throw new InvalidOperationException(Resources.Poo_Maximum_Capacity);
299-
}
300-
301222
try
302223
{
303-
Create();
224+
var newSize = Interlocked.Increment(ref _currentSize);
225+
226+
if (newSize > _maxPoolSize)
227+
{
228+
_ = Interlocked.Decrement(ref _currentSize);
229+
throw new InvalidOperationException(Resources.Poo_Maximum_Capacity);
230+
}
231+
232+
return Create();
304233
}
305234
catch
306235
{
@@ -309,16 +238,15 @@ private void TryCreateSingle()
309238
}
310239
}
311240

312-
private void Create()
241+
private T Create()
313242
{
314243
try
315244
{
316245
var item = _factory();
317246

318247
if (item != null)
319248
{
320-
_items.Add(item);
321-
return;
249+
return item;
322250
}
323251

324252
throw new InvalidOperationException(Resources.Factory_Produced_Null_Item);
@@ -361,7 +289,10 @@ private void ShrinkPool(int initPoolSize)
361289
}
362290
catch (Exception e)
363291
{
364-
Console.WriteLine(e);
292+
if (Environment.UserInteractive)
293+
{
294+
Console.WriteLine(e);
295+
}
365296
}
366297
}
367298
}

Pool/Pool.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
<RepositoryType>public</RepositoryType>
1919
<PackageTags>EasyPool</PackageTags>
2020
<PackageReleaseNotes>EasyPool</PackageReleaseNotes>
21-
<AssemblyVersion>1.1.3</AssemblyVersion>
22-
<FileVersion>1.1.3</FileVersion>
23-
<Version>1.1.3</Version>
21+
<AssemblyVersion>1.1.4</AssemblyVersion>
22+
<FileVersion>1.1.4</FileVersion>
23+
<Version>1.1.4</Version>
2424
<SignAssembly>true</SignAssembly>
2525
<PublicSign>true</PublicSign>
2626
<PackageId>EasyPool</PackageId>

0 commit comments

Comments
 (0)