-
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 all commits
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 |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
<AssemblyName>dotnetCampus.AsyncWorkerCollection</AssemblyName> | ||
<LangVersion>8</LangVersion> | ||
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. 好的 我这边主要是为了使用Rider方便些加上去的 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. @KomiSans 好奇怪,居然你不用VS开发 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. Rider更智能一些其实 |
||
</PropertyGroup> | ||
|
||
<ItemGroup Condition="'$(TargetFramework)'!='net45' AND '$(TargetFramework)'!='netstandard2.0'"> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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> | ||
/// 创建双缓存 | ||
|
@@ -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; | ||
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. 好的,我去改过来 |
||
return ReferenceEquals(CurrentList, AList) ? BList : AList; | ||
} | ||
} | ||
|
||
|
@@ -109,6 +101,7 @@ internal bool GetIsEmpty() | |
/// 用于给其他类型的同步使用的对象 | ||
/// </summary> | ||
internal object SyncObject => _lock; | ||
|
||
private readonly object _lock = new object(); | ||
|
||
private T CurrentList { set; get; } | ||
|
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.
请问,这个地方的初始化语法镇压有什么特殊含义么?
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.
@Komi-Thaw 只是让 Resharper 开心而已
这里明确给定
_autoCancelPreviousTask
的初始值为 false 的值,和默认 bool 行为相同,此时 Resharper 没有理解意图,毕竟执行逻辑是等价的,于是提示这个 false 可以删除。但是这里我期望是明确给定 false 初始值,以便在后续有期望更改为 true 的时候,可以看到,之前的设计就是明确要 false 值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.
好的