Skip to content

Commit 599297b

Browse files
authored
Merge pull request #18 from dotnet-campus/t/lindexi/WalhayqeelereWenewhearca
提供释放的方法
2 parents 175110d + a3644de commit 599297b

File tree

5 files changed

+337
-20
lines changed

5 files changed

+337
-20
lines changed

.github/workflows/dotnetcore.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ jobs:
1212

1313
- name: Build with dotnet
1414
run: dotnet build --configuration Release
15+
- name: Test with dotnet
16+
run: dotnet test --configuration Release

AsyncWorkerCollection.sln

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26124.0
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.30413.136
55
MinimumVisualStudioVersion = 15.0.26124.0
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncWorkerCollection", "AsyncWorkerCollection\AsyncWorkerCollection.csproj", "{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsyncWorkerCollection", "AsyncWorkerCollection\AsyncWorkerCollection.csproj", "{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncWorkerCollection.Tests", "test\AsyncWorkerCollection.Tests\AsyncWorkerCollection.Tests.csproj", "{70F29F77-FE49-45FE-9FED-7162897CB7B2}"
79
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -14,9 +16,6 @@ Global
1416
Release|x64 = Release|x64
1517
Release|x86 = Release|x86
1618
EndGlobalSection
17-
GlobalSection(SolutionProperties) = preSolution
18-
HideSolutionNode = FALSE
19-
EndGlobalSection
2019
GlobalSection(ProjectConfigurationPlatforms) = postSolution
2120
{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2221
{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -30,5 +29,23 @@ Global
3029
{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}.Release|x64.Build.0 = Release|Any CPU
3130
{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}.Release|x86.ActiveCfg = Release|Any CPU
3231
{8A479E25-0FE9-4A67-9AED-8B7E0A46C62D}.Release|x86.Build.0 = Release|Any CPU
32+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
34+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|x64.ActiveCfg = Debug|Any CPU
35+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|x64.Build.0 = Debug|Any CPU
36+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|x86.ActiveCfg = Debug|Any CPU
37+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Debug|x86.Build.0 = Debug|Any CPU
38+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
39+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|x64.ActiveCfg = Release|Any CPU
41+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|x64.Build.0 = Release|Any CPU
42+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|x86.ActiveCfg = Release|Any CPU
43+
{70F29F77-FE49-45FE-9FED-7162897CB7B2}.Release|x86.Build.0 = Release|Any CPU
44+
EndGlobalSection
45+
GlobalSection(SolutionProperties) = preSolution
46+
HideSolutionNode = FALSE
47+
EndGlobalSection
48+
GlobalSection(ExtensibilityGlobals) = postSolution
49+
SolutionGuid = {AB058385-F511-4985-B3F0-B5862FB893AA}
3350
EndGlobalSection
3451
EndGlobal

AsyncWorkerCollection/AsyncAutoResetEvent.cs

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
1+
using System;
2+
using System.Collections.Generic;
33
using System.Threading.Tasks;
44

55
namespace dotnetCampus.Threading
@@ -8,7 +8,7 @@ namespace dotnetCampus.Threading
88
/// 异步等待的autoresetevent
99
/// WaitOneAsync方法会返回一个task,通过await方式等待
1010
/// </summary>
11-
public class AsyncAutoResetEvent
11+
public class AsyncAutoResetEvent : IDisposable
1212
{
1313
/// <summary>
1414
/// 提供一个信号初始值,确定是否有信号
@@ -19,22 +19,31 @@ public AsyncAutoResetEvent(bool initialState)
1919
_isSignaled = initialState;
2020
}
2121

22-
private static readonly Task CompletedSourceTask
23-
#if NETFRAMEWORK
24-
= Task.FromResult(true);
25-
#else
26-
= Task.CompletedTask;
27-
#endif
22+
~AsyncAutoResetEvent()
23+
{
24+
Dispose();
25+
}
2826

27+
private static readonly Task<bool> CompletedSourceTask
28+
= Task.FromResult(true);
2929

3030
/// <summary>
31-
/// 异步等待一个信号,需要await
31+
/// 异步等待一个信号,需要 await 等待
32+
/// <para></para>
33+
/// 可以通过返回值是 true 或 false 判断当前是收到信号还是此类被释放
3234
/// </summary>
33-
/// <returns></returns>
34-
public Task WaitOneAsync()
35+
/// <returns>
36+
/// 如果是正常解锁,那么返回 true 值。如果是对象调用 <see cref="Dispose"/> 释放,那么返回 false 值
37+
/// </returns>
38+
public Task<bool> WaitOneAsync()
3539
{
3640
lock (_locker)
3741
{
42+
if (_isDisposed)
43+
{
44+
throw new ObjectDisposedException(nameof(AsyncAutoResetEvent));
45+
}
46+
3847
if (_isSignaled)
3948
{
4049
// 按照 AutoResetEvent 的设计,在没有任何等待进入时,如果有设置 Set 方法,那么下一次第一个进入的等待将会通过
@@ -55,9 +64,10 @@ public Task WaitOneAsync()
5564
public void Set()
5665
{
5766
TaskCompletionSource<bool> releaseSource = null;
67+
bool result;
5868
lock (_locker)
5969
{
60-
if (_waitQueue.Any())
70+
if (_waitQueue.Count > 0)
6171
{
6272
releaseSource = _waitQueue.Dequeue();
6373
}
@@ -69,11 +79,43 @@ public void Set()
6979
_isSignaled = true;
7080
}
7181
}
82+
83+
// 如果这个类被释放了,那么返回 false 值
84+
result = !_isDisposed;
85+
}
86+
87+
releaseSource?.SetResult(result);
88+
}
89+
90+
/// <summary>
91+
/// 非线程安全 调用时将会释放所有等待 <see cref="WaitOneAsync"/> 方法
92+
/// </summary>
93+
public void Dispose()
94+
{
95+
lock (_locker)
96+
{
97+
_isDisposed = true;
7298
}
7399

74-
releaseSource?.SetResult(true);
100+
GC.SuppressFinalize(this);
101+
102+
while (true)
103+
{
104+
lock (_locker)
105+
{
106+
if (_waitQueue.Count == 0)
107+
{
108+
return;
109+
}
110+
}
111+
112+
// 修复 https://github.com/dotnet-campus/AsyncWorkerCollection/issues/16
113+
Set();
114+
}
75115
}
76116

117+
private bool _isDisposed;
118+
77119
private readonly object _locker = new object();
78120

79121
private readonly Queue<TaskCompletionSource<bool>> _waitQueue =

0 commit comments

Comments
 (0)