diff --git a/AsyncWorkerCollection/AsyncAutoResetEvent.cs b/AsyncWorkerCollection/AsyncAutoResetEvent.cs index b2015b2..5b47e99 100644 --- a/AsyncWorkerCollection/AsyncAutoResetEvent.cs +++ b/AsyncWorkerCollection/AsyncAutoResetEvent.cs @@ -14,7 +14,7 @@ namespace dotnetCampus.Threading #else public #endif - class AsyncAutoResetEvent : IDisposable + class AsyncAutoResetEvent : IDisposable { /// /// 提供一个信号初始值,确定是否有信号 @@ -72,7 +72,7 @@ public Task WaitOneAsync() /// public void Set() { - TaskCompletionSource? releaseSource = null; + TaskCompletionSource? releaseSource = default; bool result; lock (_locker) { @@ -127,8 +127,7 @@ public void Dispose() private readonly object _locker = new object(); - private readonly Queue> _waitQueue = - new Queue>(); + private readonly Queue> _waitQueue = new Queue>(); /// /// 用于在没有任何等待时让下一次等待通过 diff --git a/AsyncWorkerCollection/AsyncManualResetEvent.cs b/AsyncWorkerCollection/AsyncManualResetEvent.cs index 668a42c..20120da 100644 --- a/AsyncWorkerCollection/AsyncManualResetEvent.cs +++ b/AsyncWorkerCollection/AsyncManualResetEvent.cs @@ -11,7 +11,7 @@ namespace dotnetCampus.Threading #else public #endif - class AsyncManualResetEvent + class AsyncManualResetEvent { /// /// 提供一个信号初始值,确定是否有信号 diff --git a/AsyncWorkerCollection/AsyncQueue.cs b/AsyncWorkerCollection/AsyncQueue.cs index 4259347..a1e6e12 100644 --- a/AsyncWorkerCollection/AsyncQueue.cs +++ b/AsyncWorkerCollection/AsyncQueue.cs @@ -1,10 +1,10 @@ #nullable enable + using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; - #if !NETCOREAPP using ValueTask = System.Threading.Tasks.Task; #endif @@ -20,7 +20,7 @@ namespace dotnetCampus.Threading #else public #endif - class AsyncQueue : IDisposable, IAsyncDisposable + class AsyncQueue : IDisposable, IAsyncDisposable { private readonly SemaphoreSlim _semaphoreSlim; private readonly ConcurrentQueue _queue; @@ -119,7 +119,7 @@ public async Task DequeueAsync(CancellationToken cancellationToken = default) /// public async ValueTask WaitForCurrentFinished() { - if (_queue.Count == 0) + if (_queue.Count is 0) { return; } @@ -128,7 +128,7 @@ public async ValueTask WaitForCurrentFinished() // 有线程执行事件触发,刚好此时在创建 CurrentFinishedTask 对象 // 此时需要重新判断是否存在任务 - if (_queue.Count == 0) + if (_queue.Count is 0) { return; } @@ -155,6 +155,7 @@ public void Dispose() // 释放 DequeueAsync 方法,释放次数为 DequeueAsync 在调用的次数 _semaphoreSlim.Release(_dequeueAsyncEnterCount); } + _semaphoreSlim.Dispose(); } diff --git a/AsyncWorkerCollection/AsyncTaskQueue_/AsyncTaskQueue.cs b/AsyncWorkerCollection/AsyncTaskQueue_/AsyncTaskQueue.cs index 097db7e..a8a5f73 100644 --- a/AsyncWorkerCollection/AsyncTaskQueue_/AsyncTaskQueue.cs +++ b/AsyncWorkerCollection/AsyncTaskQueue_/AsyncTaskQueue.cs @@ -13,7 +13,7 @@ namespace dotnetCampus.Threading #else public #endif - class AsyncTaskQueue : IDisposable + class AsyncTaskQueue : IDisposable { /// /// 异步任务队列 @@ -160,16 +160,18 @@ private async Task InternalRunning() //如已从队列中删除 if (!task.Executable) continue; //添加是否已释放的判断 - if (!_isDisposing) + if (_isDisposing) { - if (UseSingleThread) - { - task.RunSynchronously(); - } - else - { - task.Start(); - } + continue; + } + + if (UseSingleThread) + { + task.RunSynchronously(); + } + else + { + task.Start(); } } } @@ -228,7 +230,9 @@ private void Dispose(bool disposing) lock (Locker) { if (_isDisposed) return; + _isDisposing = true; + if (disposing) { } @@ -273,6 +277,7 @@ public bool AutoCancelPreviousTask private bool _isDisposing; private readonly ConcurrentQueue _queue = new ConcurrentQueue(); private readonly AsyncAutoResetEvent _autoResetEvent; + // ReSharper disable once RedundantDefaultMemberInitializer private bool _autoCancelPreviousTask = false; diff --git a/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTask.cs b/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTask.cs index 9fad40a..10ae9b7 100644 --- a/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTask.cs +++ b/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTask.cs @@ -12,7 +12,7 @@ namespace dotnetCampus.Threading #else public #endif - class AwaitableTask + class AwaitableTask { /// /// 获取任务是否为不可执行状态 diff --git a/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTaskTResult.cs b/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTaskTResult.cs index 830cce4..2ad4663 100644 --- a/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTaskTResult.cs +++ b/AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTaskTResult.cs @@ -13,7 +13,7 @@ namespace dotnetCampus.Threading #else public #endif - class AwaitableTask : AwaitableTask + class AwaitableTask : AwaitableTask { /// /// 初始化可等待的任务 diff --git a/AsyncWorkerCollection/AsyncWorkerCollection.csproj b/AsyncWorkerCollection/AsyncWorkerCollection.csproj index b6ccc94..dad11d4 100644 --- a/AsyncWorkerCollection/AsyncWorkerCollection.csproj +++ b/AsyncWorkerCollection/AsyncWorkerCollection.csproj @@ -6,6 +6,7 @@ true true dotnetCampus.AsyncWorkerCollection + 8 diff --git a/AsyncWorkerCollection/ConcurrentQueueExtension.cs b/AsyncWorkerCollection/ConcurrentQueueExtension.cs index 9fee45c..e0c2d61 100644 --- a/AsyncWorkerCollection/ConcurrentQueueExtension.cs +++ b/AsyncWorkerCollection/ConcurrentQueueExtension.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Concurrent; namespace dotnetCampus.Threading { @@ -14,7 +9,6 @@ public static void Clear(this ConcurrentQueue queue) { while (queue.TryDequeue(out _)) { - } } } diff --git a/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer.cs b/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer.cs index 48674e9..1f33701 100644 --- a/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer.cs +++ b/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer.cs @@ -15,7 +15,7 @@ namespace dotnetCampus.Threading #else public #endif - class DoubleBuffer where T : class, ICollection + class DoubleBuffer where T : class, ICollection { /// /// 创建双缓存 @@ -50,16 +50,8 @@ public T SwitchBuffer() { lock (_lock) { - if (ReferenceEquals(CurrentList, AList)) - { - CurrentList = BList; - return AList; - } - else - { - CurrentList = AList; - return BList; - } + CurrentList = ReferenceEquals(CurrentList, AList) ? AList : BList; + return ReferenceEquals(CurrentList, AList) ? BList : AList; } } @@ -109,6 +101,7 @@ internal bool GetIsEmpty() /// 用于给其他类型的同步使用的对象 /// internal object SyncObject => _lock; + private readonly object _lock = new object(); private T CurrentList { set; get; } diff --git a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferLazyInitializeTask.cs b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferLazyInitializeTask.cs index cff96bf..eee47da 100644 --- a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferLazyInitializeTask.cs +++ b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferLazyInitializeTask.cs @@ -20,7 +20,7 @@ namespace dotnetCampus.Threading #else public #endif - class DoubleBufferLazyInitializeTask + class DoubleBufferLazyInitializeTask { /// /// 初始化可等待初始化之后才执行实际任务的双缓存工具 @@ -48,16 +48,9 @@ public void OnInitialized() lock (Locker) { - if (_waitForInitializationTask != null) - { - // 如果不是空 - // 那么设置任务完成 - _waitForInitializationTask.SetResult(true); - } - else - { - // 如果是空,那么 DoInner 还没进入,此时啥都不需要做 - } + // 如果不是空 + // 那么设置任务完成 + _waitForInitializationTask?.SetResult(true); } } @@ -91,15 +84,15 @@ public void AddTask(T data) private async Task DoInner(List dataList) { -// 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入 -FirstCheckInitialized: // 标签:第一个判断初始化方法 + // 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入 + FirstCheckInitialized: // 标签:第一个判断初始化方法 if (!_isInitialized) { // 还没有初始化,等待一下 // 如果此时还没有任务可以等待,那么创建一下任务 lock (Locker) { -SecondCheckInitialized: // 标签:第二个判断初始化方法 + SecondCheckInitialized: // 标签:第二个判断初始化方法 if (!_isInitialized) { // 此时的值一定是空 @@ -112,21 +105,19 @@ private async Task DoInner(List dataList) { await _waitForInitializationTask!.Task.ConfigureAwait(false); } - else - { - // 此时初始化方法被调用,因此不需要再调用等待 - // 如果先进入 FirstCheckInitialized 标签的第一个判断初始化方法,此时 OnInitialized 没有被调用 - // 因此进入分支 - // 如果刚好此时 OnInitialized 方法进入,同时设置了 _isInitialized 是 true 值 - // 如果此时的 OnInitialized 方法比 DoInner 先获得锁,那么将判断 _waitForInitializationTask 是空,啥都不做 - // 然后 DoInner 在等待 OnInitialized 的 Locker 锁,进入锁之后,先通过 SecondCheckInitialized 标签的第二个判断初始化方法 - // 这个判断是线程安全的,因此如果是 OnInitialized 已进入同时获取锁,那么此时在等待 Locker 锁之后一定拿到新的值 - // 如果是 DoInner 先获得锁,那么此时也许 _isInitialized 不靠谱,但其实不依赖 _isInitialized 靠谱,因此 _isInitialized 只有一个状态,就是从 false 到 true 的值 - // 此时如果判断 _isInitialized 是 true 的值,也就不需要再创建一个任务用来等待了 - // 也就会最终进入此分支 - } + // 此时初始化方法被调用,因此不需要再调用等待 + // 如果先进入 FirstCheckInitialized 标签的第一个判断初始化方法,此时 OnInitialized 没有被调用 + // 因此进入分支 + // 如果刚好此时 OnInitialized 方法进入,同时设置了 _isInitialized 是 true 值 + // 如果此时的 OnInitialized 方法比 DoInner 先获得锁,那么将判断 _waitForInitializationTask 是空,啥都不做 + // 然后 DoInner 在等待 OnInitialized 的 Locker 锁,进入锁之后,先通过 SecondCheckInitialized 标签的第二个判断初始化方法 + // 这个判断是线程安全的,因此如果是 OnInitialized 已进入同时获取锁,那么此时在等待 Locker 锁之后一定拿到新的值 + // 如果是 DoInner 先获得锁,那么此时也许 _isInitialized 不靠谱,但其实不依赖 _isInitialized 靠谱,因此 _isInitialized 只有一个状态,就是从 false 到 true 的值 + // 此时如果判断 _isInitialized 是 true 的值,也就不需要再创建一个任务用来等待了 + // 也就会最终进入此分支 // 只需要等待一次,然后可以释放内存 + _waitForInitializationTask = null; } diff --git a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask.cs b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask.cs index 2934015..45c3c37 100644 --- a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask.cs +++ b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask.cs @@ -18,7 +18,7 @@ namespace dotnetCampus.Threading #else public #endif - class DoubleBufferTask : IAsyncDisposable + class DoubleBufferTask : IAsyncDisposable where T : class, ICollection { /// @@ -50,7 +50,7 @@ public void AddTask(TU t) if (isSetFinish == 1) { // 被设置完成了,业务上就不应该再次给任何的数据内容 - throw new InvalidOperationException($"The DoubleBufferTask has been set finish."); + throw new InvalidOperationException("The DoubleBufferTask has been set finish."); } DoubleBuffer.Add(t); @@ -74,12 +74,14 @@ private async Task DoInner() lock (Locker) { - if (DoubleBuffer.GetIsEmpty()) + if (!DoubleBuffer.GetIsEmpty()) { - _isDoing = false; - Finished?.Invoke(this, EventArgs.Empty); - break; + continue; } + + _isDoing = false; + Finished?.Invoke(this, EventArgs.Empty); + break; } } } diff --git a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask`T.cs b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask`T.cs index 2ea9d27..b434af0 100644 --- a/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask`T.cs +++ b/AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask`T.cs @@ -14,7 +14,7 @@ namespace dotnetCampus.Threading #else public #endif - class DoubleBufferTask : DoubleBufferTask, T> + class DoubleBufferTask : DoubleBufferTask, T> { /// /// 创建双缓存任务,执行任务的方法放在 方法 diff --git a/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer`T.cs b/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer`T.cs index 1990949..74867ac 100644 --- a/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer`T.cs +++ b/AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer`T.cs @@ -11,7 +11,7 @@ namespace dotnetCampus.Threading #else public #endif - class DoubleBuffer : DoubleBuffer, T> + class DoubleBuffer : DoubleBuffer, T> { /// /// 创建使用 的双缓存 diff --git a/AsyncWorkerCollection/ExecuteOnceAwaiter.cs b/AsyncWorkerCollection/ExecuteOnceAwaiter.cs index 8d83631..443bb30 100644 --- a/AsyncWorkerCollection/ExecuteOnceAwaiter.cs +++ b/AsyncWorkerCollection/ExecuteOnceAwaiter.cs @@ -13,7 +13,7 @@ namespace dotnetCampus.Threading #else public #endif - class ExecuteOnceAwaiter + class ExecuteOnceAwaiter { /// /// 创建只执行一次的等待,调用 时,无论调用多少次,只会执行 一次 @@ -53,7 +53,7 @@ public void ResetWhileCompleted() { if (_executionResult?.IsCompleted is true) { - _executionResult = null; + _executionResult = default; } } } @@ -61,6 +61,7 @@ public void ResetWhileCompleted() private readonly object _locker = new object(); private readonly Func> _asyncAction; + private Task _executionResult; } } diff --git a/AsyncWorkerCollection/LimitedRunningCountTask.cs b/AsyncWorkerCollection/LimitedRunningCountTask.cs index 567d792..8f1480c 100644 --- a/AsyncWorkerCollection/LimitedRunningCountTask.cs +++ b/AsyncWorkerCollection/LimitedRunningCountTask.cs @@ -87,9 +87,9 @@ public async ValueTask AddAsync(Task task) /// 等待空闲 /// /// - public async ValueTask WaitForFree() + private async ValueTask WaitForFree() { - if (WaitForFreeTask == null) + if (WaitForFreeTask is null) { return; } @@ -148,18 +148,11 @@ private TaskCompletionSource? WaitForFreeTask private async Task RunningInner() { // ReSharper disable once InconsistentlySynchronizedField - if (_isRunning) - { - return; - } + if (_isRunning) return; lock (Locker) { - if (_isRunning) - { - return; - } - + if (_isRunning) return; _isRunning = true; } @@ -217,16 +210,11 @@ private async Task RunningInner() void SetWaitForFreeTask() { - if (runningTaskList.Count > MaxRunningCount) - { - if (WaitForFreeTask?.Task.IsCompleted is false) - { - } - else - { - WaitForFreeTask = new TaskCompletionSource(); - } - } + if (runningTaskList.Count <= MaxRunningCount) return; + + if (WaitForFreeTask?.Task.IsCompleted is false) return; + + WaitForFreeTask = new TaskCompletionSource(); } } } diff --git a/AsyncWorkerCollection/Reentrancy/KeepLastReentrancyTask.cs b/AsyncWorkerCollection/Reentrancy/KeepLastReentrancyTask.cs index 045d3b6..57bb16e 100644 --- a/AsyncWorkerCollection/Reentrancy/KeepLastReentrancyTask.cs +++ b/AsyncWorkerCollection/Reentrancy/KeepLastReentrancyTask.cs @@ -22,7 +22,7 @@ namespace dotnetCampus.Threading.Reentrancy #else public #endif - sealed class KeepLastReentrancyTask : ReentrancyTask + sealed class KeepLastReentrancyTask : ReentrancyTask { /// /// 用于原子操作判断当前是否正在执行队列中的可重入任务。 @@ -192,8 +192,10 @@ internal async Task RunAsync() var task = _task(); if (task is null) { - throw new InvalidOperationException("在指定 KeepLastReentrancyTask 的任务时,方法内不允许返回 null。请至少返回 Task.FromResult(null)。"); + throw new InvalidOperationException( + "在指定 KeepLastReentrancyTask 的任务时,方法内不允许返回 null。请至少返回 Task.FromResult(null)。"); } + var result = await task.ConfigureAwait(_configureAwait); _taskSource.SetResult(result); Result = result; diff --git a/AsyncWorkerCollection/Reentrancy/QueueReentrancyTask.cs b/AsyncWorkerCollection/Reentrancy/QueueReentrancyTask.cs index 62d9c13..1dd9329 100644 --- a/AsyncWorkerCollection/Reentrancy/QueueReentrancyTask.cs +++ b/AsyncWorkerCollection/Reentrancy/QueueReentrancyTask.cs @@ -21,7 +21,7 @@ namespace dotnetCampus.Threading.Reentrancy #else public #endif - sealed class QueueReentrancyTask : ReentrancyTask + sealed class QueueReentrancyTask : ReentrancyTask { /// /// 用于原子操作判断当前是否正在执行队列中的可重入任务。 diff --git a/AsyncWorkerCollection/Reentrancy/ReentrancyTask.cs b/AsyncWorkerCollection/Reentrancy/ReentrancyTask.cs index 675ca32..940b885 100644 --- a/AsyncWorkerCollection/Reentrancy/ReentrancyTask.cs +++ b/AsyncWorkerCollection/Reentrancy/ReentrancyTask.cs @@ -19,12 +19,12 @@ namespace dotnetCampus.Threading.Reentrancy #else public #endif - abstract class ReentrancyTask + abstract class ReentrancyTask { /// /// 在派生类中执行重入任务的时候,从此处获取需要执行的可重入异步任务。 /// - protected Func> WorkingTask { get; } + private Func> WorkingTask { get; } /// /// 初始化可重入任务的公共基类。