File tree Expand file tree Collapse file tree 2 files changed +21
-4
lines changed Expand file tree Collapse file tree 2 files changed +21
-4
lines changed Original file line number Diff line number Diff line change 1
- using System . Collections . Concurrent ;
1
+ using System ;
2
+ using System . Collections . Concurrent ;
2
3
using System . Collections . Generic ;
3
4
using System . Threading ;
4
5
using System . Threading . Tasks ;
@@ -9,7 +10,7 @@ namespace dotnetCampus.Threading
9
10
/// 提供一个异步的队列。可以使用 await 关键字异步等待出队,当有元素入队的时候,等待就会完成。
10
11
/// </summary>
11
12
/// <typeparam name="T">存入异步队列中的元素类型。</typeparam>
12
- public class AsyncQueue < T >
13
+ public class AsyncQueue < T > : IDisposable
13
14
{
14
15
private readonly SemaphoreSlim _semaphoreSlim ;
15
16
private readonly ConcurrentQueue < T > _queue ;
@@ -64,7 +65,7 @@ public void EnqueueRange(IEnumerable<T> source)
64
65
/// <returns>可以异步等待的队列返回的元素。</returns>
65
66
public async Task < T > DequeueAsync ( CancellationToken cancellationToken = default )
66
67
{
67
- while ( true )
68
+ while ( ! _isDisposed )
68
69
{
69
70
await _semaphoreSlim . WaitAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
70
71
@@ -73,6 +74,22 @@ public async Task<T> DequeueAsync(CancellationToken cancellationToken = default)
73
74
return item ;
74
75
}
75
76
}
77
+
78
+ return default ;
76
79
}
80
+
81
+ /// <summary>
82
+ /// 主要用来释放锁,让 DequeueAsync 方法返回,解决因为锁让此对象内存不释放
83
+ /// </summary>
84
+ public void Dispose ( )
85
+ {
86
+ // 当释放的时候,将通过 _queue 的 Clear 清空内容,而通过 _semaphoreSlim 的释放让 DequeueAsync 释放锁
87
+ // 此时将会在 DequeueAsync 进入 TryDequeue 方法,也许此时依然有开发者在 _queue.Clear() 之后插入元素,但是没关系,我只是需要保证调用 Dispose 之后会让 DequeueAsync 方法返回而已
88
+ _isDisposed = true ;
89
+ _queue . Clear ( ) ;
90
+ _semaphoreSlim . Dispose ( ) ;
91
+ }
92
+
93
+ private bool _isDisposed ;
77
94
}
78
95
}
Original file line number Diff line number Diff line change 6
6
namespace dotnetCampus . Threading
7
7
{
8
8
/// <summary>
9
- /// 异步任务队列
9
+ /// 异步任务队列,这是重量级的方案,将会开启一个线程来做
10
10
/// </summary>
11
11
public class AsyncTaskQueue : IDisposable
12
12
{
You can’t perform that action at this time.
0 commit comments