Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions AsyncWorkerCollection/AsyncAutoResetEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AsyncAutoResetEvent : IDisposable
class AsyncAutoResetEvent : IDisposable
{
/// <summary>
/// 提供一个信号初始值,确定是否有信号
Expand Down Expand Up @@ -72,7 +72,7 @@ public Task<bool> WaitOneAsync()
/// </summary>
public void Set()
{
TaskCompletionSource<bool>? releaseSource = null;
TaskCompletionSource<bool>? releaseSource = default;
bool result;
lock (_locker)
{
Expand Down Expand Up @@ -125,10 +125,9 @@ public void Dispose()

private bool _isDisposed;

private readonly object _locker = new object();
private readonly object _locker = new();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

由于采用源代码形式分发,考虑到源代码兼容性,不打算采用此语法特性


private readonly Queue<TaskCompletionSource<bool>> _waitQueue =
new Queue<TaskCompletionSource<bool>>();
private readonly Queue<TaskCompletionSource<bool>> _waitQueue = new();

/// <summary>
/// 用于在没有任何等待时让下一次等待通过
Expand Down
2 changes: 1 addition & 1 deletion AsyncWorkerCollection/AsyncManualResetEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AsyncManualResetEvent
class AsyncManualResetEvent
{
/// <summary>
/// 提供一个信号初始值,确定是否有信号
Expand Down
12 changes: 6 additions & 6 deletions AsyncWorkerCollection/AsyncQueue.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -20,7 +20,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AsyncQueue<T> : IDisposable, IAsyncDisposable
class AsyncQueue<T> : IDisposable, IAsyncDisposable
{
private readonly SemaphoreSlim _semaphoreSlim;
private readonly ConcurrentQueue<T> _queue;
Expand Down Expand Up @@ -119,7 +119,7 @@ public async Task<T> DequeueAsync(CancellationToken cancellationToken = default)
/// <returns></returns>
public async ValueTask WaitForCurrentFinished()
{
if (_queue.Count == 0)
if (_queue.Count is 0)
{
return;
}
Expand All @@ -128,7 +128,7 @@ public async ValueTask WaitForCurrentFinished()

// 有线程执行事件触发,刚好此时在创建 CurrentFinishedTask 对象
// 此时需要重新判断是否存在任务
if (_queue.Count == 0)
if (_queue.Count is 0)
{
return;
}
Expand All @@ -155,6 +155,7 @@ public void Dispose()
// 释放 DequeueAsync 方法,释放次数为 DequeueAsync 在调用的次数
_semaphoreSlim.Release(_dequeueAsyncEnterCount);
}

_semaphoreSlim.Dispose();
}

Expand Down Expand Up @@ -221,8 +222,7 @@ public async ValueTask WaitForCurrentFinished()
await _currentFinishedTaskCompletionSource.Task.ConfigureAwait(false);
}

private readonly TaskCompletionSource<bool> _currentFinishedTaskCompletionSource =
new TaskCompletionSource<bool>();
private readonly TaskCompletionSource<bool> _currentFinishedTaskCompletionSource = new();

private readonly AsyncQueue<T> _asyncQueue;

Expand Down
33 changes: 19 additions & 14 deletions AsyncWorkerCollection/AsyncTaskQueue_/AsyncTaskQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AsyncTaskQueue : IDisposable
class AsyncTaskQueue : IDisposable
{
/// <summary>
/// 异步任务队列
Expand Down Expand Up @@ -160,16 +160,18 @@ private async void InternalRunning()
//如已从队列中删除
if (!task.Executable) continue;
//添加是否已释放的判断
if (!_isDisposing)
if (_isDisposing)
{
if (UseSingleThread)
{
task.RunSynchronously();
}
else
{
task.Start();
}
continue;
}

if (UseSingleThread)
{
task.RunSynchronously();
}
else
{
task.Start();
}
}
}
Expand All @@ -182,8 +184,8 @@ private async void InternalRunning()

private bool TryGetNextTask(out AwaitableTask task)
{
task = null;
while (_queue.Count > 0)
task = default;
while (_queue.Count is 0)
Copy link
Copy Markdown
Member

@lindexi lindexi Oct 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个逻辑是错误的

这里是不断获取队列内容

{
//获取并从队列中移除任务
if (_queue.TryDequeue(out task) && (!AutoCancelPreviousTask || _queue.Count == 0))
Expand All @@ -199,7 +201,7 @@ private bool TryGetNextTask(out AwaitableTask task)
task.SetNotExecutable();
}

return false;
return default;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于布尔来说,使用 false 更加表意

}

#endregion
Expand Down Expand Up @@ -228,7 +230,9 @@ private void Dispose(bool disposing)
lock (Locker)
{
if (_isDisposed) return;

_isDisposing = true;

if (disposing)
{
}
Expand Down Expand Up @@ -271,8 +275,9 @@ public bool AutoCancelPreviousTask
private object Locker => _queue;
private bool _isDisposed;
private bool _isDisposing;
private readonly ConcurrentQueue<AwaitableTask> _queue = new ConcurrentQueue<AwaitableTask>();
private readonly ConcurrentQueue<AwaitableTask> _queue = new();
private readonly AsyncAutoResetEvent _autoResetEvent;

// ReSharper disable once RedundantDefaultMemberInitializer
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请问,这个地方的初始化语法镇压有什么特殊含义么?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Komi-Thaw 只是让 Resharper 开心而已

这里明确给定 _autoCancelPreviousTask 的初始值为 false 的值,和默认 bool 行为相同,此时 Resharper 没有理解意图,毕竟执行逻辑是等价的,于是提示这个 false 可以删除。但是这里我期望是明确给定 false 初始值,以便在后续有期望更改为 true 的时候,可以看到,之前的设计就是明确要 false 值

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的

private bool _autoCancelPreviousTask = false;

Expand Down
6 changes: 3 additions & 3 deletions AsyncWorkerCollection/AsyncTaskQueue_/AwaitableTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AwaitableTask
class AwaitableTask
{
/// <summary>
/// 获取任务是否为不可执行状态
Expand All @@ -30,15 +30,15 @@ class AwaitableTask
/// </summary>
public void SetNotExecutable()
{
Executable = false;
Executable = default;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于布尔来说,使用 true 和 false 更加表意

}

/// <summary>
/// 标记任务无效
/// </summary>
public void MarkTaskInvalid()
{
IsValid = false;
IsValid = default;
}

#region Task
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class AwaitableTask<TResult> : AwaitableTask
class AwaitableTask<TResult> : AwaitableTask
{
/// <summary>
/// 初始化可等待的任务
Expand Down
8 changes: 1 addition & 7 deletions AsyncWorkerCollection/ConcurrentQueueExtension.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -14,7 +9,6 @@ public static void Clear<T>(this ConcurrentQueue<T> queue)
{
while (queue.TryDequeue(out _))
{

}
}
}
Expand Down
3 changes: 2 additions & 1 deletion AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class DoubleBuffer<T, TU> where T : class, ICollection<TU>
class DoubleBuffer<T, TU> where T : class, ICollection<TU>
{
/// <summary>
/// 创建双缓存
Expand Down Expand Up @@ -109,6 +109,7 @@ internal bool GetIsEmpty()
/// 用于给其他类型的同步使用的对象
/// </summary>
internal object SyncObject => _lock;

private readonly object _lock = new object();

private T CurrentList { set; get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class DoubleBufferLazyInitializeTask<T>
class DoubleBufferLazyInitializeTask<T>
{
/// <summary>
/// 初始化可等待初始化之后才执行实际任务的双缓存工具
Expand Down Expand Up @@ -48,16 +48,9 @@ public void OnInitialized()

lock (Locker)
{
if (_waitForInitializationTask != null)
{
// 如果不是空
// 那么设置任务完成
_waitForInitializationTask.SetResult(true);
}
else
{
// 如果是空,那么 DoInner 还没进入,此时啥都不需要做
}
// 如果不是空
// 那么设置任务完成
_waitForInitializationTask?.SetResult(true);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原本的写法是表示空和非空都在处理逻辑内,而且也方便加上断点进行调试。这个逻辑不做简化

}
}

Expand Down Expand Up @@ -91,15 +84,15 @@ public void AddTask(T data)

private async Task DoInner(List<T> dataList)
{
// 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入
FirstCheckInitialized: // 标签:第一个判断初始化方法
// 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入
FirstCheckInitialized: // 标签:第一个判断初始化方法
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里用到部分 Goto 的方式,似乎对标签的缩进格式有所不同。我比较喜欢使用不缩进的方式,用来表示标签就是和其他代码不同

if (!_isInitialized)
{
// 还没有初始化,等待一下
// 如果此时还没有任务可以等待,那么创建一下任务
lock (Locker)
{
SecondCheckInitialized: // 标签:第二个判断初始化方法
SecondCheckInitialized: // 标签:第二个判断初始化方法
if (!_isInitialized)
{
// 此时的值一定是空
Expand All @@ -112,21 +105,19 @@ private async Task DoInner(List<T> dataList)
{
await _waitForInitializationTask!.Task.ConfigureAwait(false);
}
else
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个空 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;
}

Expand Down
12 changes: 7 additions & 5 deletions AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class DoubleBufferTask<T, TU> : IAsyncDisposable
class DoubleBufferTask<T, TU> : IAsyncDisposable
where T : class, ICollection<TU>
{
/// <summary>
Expand Down Expand Up @@ -74,12 +74,14 @@ private async void 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;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion AsyncWorkerCollection/DoubleBuffer_/DoubleBufferTask`T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class DoubleBufferTask<T> : DoubleBufferTask<List<T>, T>
class DoubleBufferTask<T> : DoubleBufferTask<List<T>, T>
{
/// <summary>
/// 创建双缓存任务,执行任务的方法放在 <paramref name="doTask"/> 方法
Expand Down
2 changes: 1 addition & 1 deletion AsyncWorkerCollection/DoubleBuffer_/DoubleBuffer`T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace dotnetCampus.Threading
#else
public
#endif
class DoubleBuffer<T> : DoubleBuffer<List<T>, T>
class DoubleBuffer<T> : DoubleBuffer<List<T>, T>
{
/// <summary>
/// 创建使用 <see cref="List&lt;T&gt;"/> 的双缓存
Expand Down
Loading