@@ -12,18 +12,77 @@ namespace CodeJam.Threading
12
12
[ TestFixture ]
13
13
public class AsyncLockTest
14
14
{
15
+ private static async Task < bool > TryTakeAndHold (
16
+ AsyncLock asyncLock , TimeSpan holdTime , CancellationToken cancellation = default ( CancellationToken ) , Action callback = null )
17
+ {
18
+ try
19
+ {
20
+ using ( await asyncLock . AcquireAsync ( holdTime , cancellation ) )
21
+ {
22
+ callback ? . Invoke ( ) ;
23
+ await Task . Delay ( holdTime ) ;
24
+ }
25
+ return true ;
26
+ }
27
+ catch ( OperationCanceledException )
28
+ {
29
+ return false ;
30
+ }
31
+ catch ( TimeoutException )
32
+ {
33
+ return false ;
34
+ }
35
+ }
36
+
37
+ [ Test ]
38
+ [ SuppressMessage ( "ReSharper" , "MethodSupportsCancellation" ) ]
39
+ public async Task LockCancellationTest ( )
40
+ {
41
+ var asyncLock = new AsyncLock ( ) ;
42
+ var holdTime = TimeSpan . FromSeconds ( 8 ) ;
43
+ var delayTime = TimeSpan . FromMilliseconds ( 200 ) ;
44
+
45
+ var lock1Started = new ManualResetEventSlim ( false ) ;
46
+
47
+ var lock1 = TryTakeAndHold ( asyncLock , holdTime , callback : ( ) => lock1Started . Set ( ) ) ;
48
+ lock1Started . Wait ( ) ;
49
+
50
+ var cts2 = new CancellationTokenSource ( ) ;
51
+ var sw2 = Stopwatch . StartNew ( ) ;
52
+ var lock2 = TryTakeAndHold ( asyncLock , holdTime , cts2 . Token ) ;
53
+ await Task . Delay ( delayTime ) ;
54
+ cts2 . Cancel ( ) ;
55
+ var lock2Taken = await lock2 ;
56
+ sw2 . Stop ( ) ;
57
+
58
+ var sw3 = Stopwatch . StartNew ( ) ;
59
+ var lock3 = TryTakeAndHold ( asyncLock , delayTime ) ;
60
+ await Task . Delay ( delayTime ) ;
61
+ var lock3Taken = await lock3 ;
62
+ sw3 . Stop ( ) ;
63
+
64
+ var lock1Taken = await lock1 ;
65
+
66
+ Assert . IsTrue ( lock1Taken ) ;
67
+ Assert . IsFalse ( lock2Taken ) ;
68
+ Assert . Less ( sw2 . Elapsed , holdTime - delayTime ) ;
69
+ Assert . IsFalse ( lock3Taken ) ;
70
+ Assert . Less ( sw3 . Elapsed , holdTime - delayTime ) ;
71
+ }
72
+
15
73
[ Test ]
16
74
public async Task LockTest ( )
17
75
{
18
76
var asyncLock = new AsyncLock ( ) ;
77
+
19
78
var opActive = false ;
20
79
const int time = 200 ;
21
80
const int timeInc = 10 ;
22
81
const int count = 10 ;
23
82
24
83
async Task Op ( int num )
25
84
{
26
- using ( await asyncLock . Acquire ( ) )
85
+ using ( await asyncLock . AcquireAsync ( ) )
27
86
{
28
87
Assert . IsFalse ( opActive ) ;
29
88
opActive = true ;
@@ -42,36 +101,5 @@ await Enumerable
42
101
Assert . IsFalse ( opActive ) ;
43
102
Assert . GreaterOrEqual ( sw . ElapsedMilliseconds , time * count + timeInc * count / 2 ) ;
44
103
}
45
-
46
- [ Test ]
47
- [ SuppressMessage ( "ReSharper" , "MethodSupportsCancellation" ) ]
48
- public async Task Cancellation ( )
49
- {
50
- var cts = new CancellationTokenSource ( ) ;
51
- var lck = new AsyncLock ( ) ;
52
- const int delay = 5000 ;
53
- const int ensureLockInterval = 30 ;
54
- Task . Run (
55
- async ( ) =>
56
- {
57
- using ( await lck . Acquire ( ) )
58
- await Task . Delay ( delay ) ;
59
- } ) ;
60
- await Task . Delay ( ensureLockInterval ) ;
61
- var sw = Stopwatch . StartNew ( ) ;
62
- var task = Task . Run (
63
- async ( ) =>
64
- {
65
- using ( await lck . Acquire ( cts . Token ) )
66
- sw . Stop ( ) ;
67
- } ) ;
68
- cts . Cancel ( ) ;
69
- try
70
- {
71
- await task ;
72
- }
73
- catch ( TaskCanceledException ) { }
74
- Assert . Less ( sw . ElapsedMilliseconds , delay - ensureLockInterval ) ;
75
- }
76
104
}
77
105
}
0 commit comments