-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
init:.Net 6版本初始化 #70
base: master
Are you sure you want to change the base?
init:.Net 6版本初始化 #70
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ namespace dotnetCampus.Threading | |
#else | ||
public | ||
#endif | ||
class AsyncTaskQueue : IDisposable | ||
class AsyncTaskQueue : IDisposable | ||
{ | ||
/// <summary> | ||
/// 异步任务队列 | ||
|
@@ -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(); | ||
} | ||
} | ||
} | ||
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个逻辑是错误的 这里是不断获取队列内容 |
||
{ | ||
//获取并从队列中移除任务 | ||
if (_queue.TryDequeue(out task) && (!AutoCancelPreviousTask || _queue.Count == 0)) | ||
|
@@ -199,7 +201,7 @@ private bool TryGetNextTask(out AwaitableTask task) | |
task.SetNotExecutable(); | ||
} | ||
|
||
return false; | ||
return default; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 对于布尔来说,使用 false 更加表意 |
||
} | ||
|
||
#endregion | ||
|
@@ -228,7 +230,9 @@ private void Dispose(bool disposing) | |
lock (Locker) | ||
{ | ||
if (_isDisposed) return; | ||
|
||
_isDisposing = true; | ||
|
||
if (disposing) | ||
{ | ||
} | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 请问,这个地方的初始化语法镇压有什么特殊含义么? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Komi-Thaw 只是让 Resharper 开心而已 这里明确给定 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 好的 |
||
private bool _autoCancelPreviousTask = false; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ namespace dotnetCampus.Threading | |
#else | ||
public | ||
#endif | ||
class AwaitableTask | ||
class AwaitableTask | ||
{ | ||
/// <summary> | ||
/// 获取任务是否为不可执行状态 | ||
|
@@ -30,15 +30,15 @@ class AwaitableTask | |
/// </summary> | ||
public void SetNotExecutable() | ||
{ | ||
Executable = false; | ||
Executable = default; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ namespace dotnetCampus.Threading | |
#else | ||
public | ||
#endif | ||
class DoubleBufferLazyInitializeTask<T> | ||
class DoubleBufferLazyInitializeTask<T> | ||
{ | ||
/// <summary> | ||
/// 初始化可等待初始化之后才执行实际任务的双缓存工具 | ||
|
@@ -48,16 +48,9 @@ public void OnInitialized() | |
|
||
lock (Locker) | ||
{ | ||
if (_waitForInitializationTask != null) | ||
{ | ||
// 如果不是空 | ||
// 那么设置任务完成 | ||
_waitForInitializationTask.SetResult(true); | ||
} | ||
else | ||
{ | ||
// 如果是空,那么 DoInner 还没进入,此时啥都不需要做 | ||
} | ||
// 如果不是空 | ||
// 那么设置任务完成 | ||
_waitForInitializationTask?.SetResult(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 原本的写法是表示空和非空都在处理逻辑内,而且也方便加上断点进行调试。这个逻辑不做简化 |
||
} | ||
} | ||
|
||
|
@@ -91,15 +84,15 @@ public void AddTask(T data) | |
|
||
private async Task DoInner(List<T> dataList) | ||
{ | ||
// 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入 | ||
FirstCheckInitialized: // 标签:第一个判断初始化方法 | ||
// 根据 DoubleBufferTask 的设计,这个方法只有一个线程进入 | ||
FirstCheckInitialized: // 标签:第一个判断初始化方法 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里用到部分 Goto 的方式,似乎对标签的缩进格式有所不同。我比较喜欢使用不缩进的方式,用来表示标签就是和其他代码不同 |
||
if (!_isInitialized) | ||
{ | ||
// 还没有初始化,等待一下 | ||
// 如果此时还没有任务可以等待,那么创建一下任务 | ||
lock (Locker) | ||
{ | ||
SecondCheckInitialized: // 标签:第二个判断初始化方法 | ||
SecondCheckInitialized: // 标签:第二个判断初始化方法 | ||
if (!_isInitialized) | ||
{ | ||
// 此时的值一定是空 | ||
|
@@ -112,21 +105,19 @@ private async Task DoInner(List<T> dataList) | |
{ | ||
await _waitForInitializationTask!.Task.ConfigureAwait(false); | ||
} | ||
else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
由于采用源代码形式分发,考虑到源代码兼容性,不打算采用此语法特性