@@ -18,32 +18,37 @@ public class AsyncTaskMethodBuilderTests
18
18
public static void VoidMethodBuilder_TrackedContext ( )
19
19
{
20
20
SynchronizationContext previousContext = SynchronizationContext . Current ;
21
- var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
22
- SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
23
-
24
- // TrackedCount should increase as Create() is called, and decrease as SetResult() is called.
25
-
26
- // Completing in opposite order as created.
27
- var avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
28
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
29
- var avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
30
- Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
31
- avmb2 . SetResult ( ) ;
32
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
33
- avmb1 . SetResult ( ) ;
34
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
35
-
36
- // Completing in same order as created
37
- avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
38
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
39
- avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
40
- Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
41
- avmb1 . SetResult ( ) ;
42
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
43
- avmb2 . SetResult ( ) ;
44
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
45
-
46
- SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
21
+ try
22
+ {
23
+ var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
24
+ SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
25
+
26
+ // TrackedCount should increase as Create() is called, and decrease as SetResult() is called.
27
+
28
+ // Completing in opposite order as created.
29
+ var avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
30
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
31
+ var avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
32
+ Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
33
+ avmb2 . SetResult ( ) ;
34
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
35
+ avmb1 . SetResult ( ) ;
36
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
37
+
38
+ // Completing in same order as created
39
+ avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
40
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
41
+ avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
42
+ Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
43
+ avmb1 . SetResult ( ) ;
44
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
45
+ avmb2 . SetResult ( ) ;
46
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
47
+ }
48
+ finally
49
+ {
50
+ SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
51
+ }
47
52
}
48
53
49
54
// Test not having a sync context with successful completion (SetResult)
@@ -83,14 +88,20 @@ public static void TaskMethodBuilder_DoesNotTouchSyncContext()
83
88
{
84
89
// Verify that AsyncTaskMethodBuilder is not touching sync context
85
90
SynchronizationContext previousContext = SynchronizationContext . Current ;
86
- var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
87
- SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
91
+ try
92
+ {
93
+ var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
94
+ SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
88
95
89
- var atmb = AsyncTaskMethodBuilder . Create ( ) ;
90
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
91
- atmb . SetResult ( ) ;
92
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
93
- SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
96
+ var atmb = AsyncTaskMethodBuilder . Create ( ) ;
97
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
98
+ atmb . SetResult ( ) ;
99
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
100
+ }
101
+ finally
102
+ {
103
+ SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
104
+ }
94
105
}
95
106
96
107
// AsyncTaskMethodBuilder<T>
@@ -112,20 +123,24 @@ public static void TaskMethodBuilderT_DoesNotTouchSyncContext()
112
123
{
113
124
// Verify that AsyncTaskMethodBuilder<T> is not touching sync context
114
125
SynchronizationContext previousContext = SynchronizationContext . Current ;
115
- var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
116
- SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
117
-
118
- var atmb = AsyncTaskMethodBuilder < string > . Create ( ) ;
119
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
120
- atmb . SetResult ( "async" ) ;
121
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
126
+ try
127
+ {
128
+ var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
129
+ SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
122
130
123
- SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
131
+ var atmb = AsyncTaskMethodBuilder < string > . Create ( ) ;
132
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
133
+ atmb . SetResult ( "async" ) ;
134
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
135
+ }
136
+ finally
137
+ {
138
+ SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
139
+ }
124
140
}
125
141
126
142
// Incorrect usage for AsyncTaskMethodBuilder
127
143
[ Fact ]
128
- [ ActiveIssue ( "Hangs" ) ]
129
144
public static void TaskMethodBuilder_IncorrectUsage ( )
130
145
{
131
146
var atmb = new AsyncTaskMethodBuilder ( ) ;
@@ -134,11 +149,11 @@ public static void TaskMethodBuilder_IncorrectUsage()
134
149
135
150
// Incorrect usage for AsyncVoidMethodBuilder
136
151
[ Fact ]
137
- [ ActiveIssue ( "Hangs" ) ]
138
152
public static void VoidMethodBuilder_IncorrectUsage ( )
139
153
{
140
154
var avmb = AsyncVoidMethodBuilder . Create ( ) ;
141
155
Assert . Throws < ArgumentNullException > ( ( ) => { avmb . SetException ( null ) ; } ) ;
156
+ avmb . SetResult ( ) ;
142
157
}
143
158
144
159
// Creating a task builder, building it, completing it successfully, and making sure it can't be reset
@@ -221,39 +236,43 @@ public static void AsyncMethodBuilderCreate_SetExceptionTest2()
221
236
// Test captured sync context with exceptional completion
222
237
223
238
SynchronizationContext previousContext = SynchronizationContext . Current ;
224
-
225
- var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
226
- SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
227
-
228
- // Completing in opposite order as created
229
- var avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
230
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
231
- var avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
232
- Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
233
- avmb2 . SetException ( new InvalidOperationException ( "uh oh 1" ) ) ;
234
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
235
- avmb1 . SetException ( new InvalidCastException ( "uh oh 2" ) ) ;
236
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
237
-
238
- Assert . Equal ( 2 , trackedContext . PostExceptions . Count ) ;
239
- Assert . IsType < InvalidOperationException > ( trackedContext . PostExceptions [ 0 ] ) ;
240
- Assert . IsType < InvalidCastException > ( trackedContext . PostExceptions [ 1 ] ) ;
241
-
242
- // Completing in same order as created
243
- var avmb3 = AsyncVoidMethodBuilder . Create ( ) ;
244
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
245
- var avmb4 = AsyncVoidMethodBuilder . Create ( ) ;
246
- Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
247
- avmb3 . SetException ( new InvalidOperationException ( "uh oh 3" ) ) ;
248
- Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
249
- avmb4 . SetException ( new InvalidCastException ( "uh oh 4" ) ) ;
250
- Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
251
-
252
- Assert . Equal ( 4 , trackedContext . PostExceptions . Count ) ;
253
- Assert . IsType < InvalidOperationException > ( trackedContext . PostExceptions [ 2 ] ) ;
254
- Assert . IsType < InvalidCastException > ( trackedContext . PostExceptions [ 3 ] ) ;
255
-
256
- SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
239
+ try
240
+ {
241
+ var trackedContext = new TrackOperationsSynchronizationContext ( ) ;
242
+ SynchronizationContext . SetSynchronizationContext ( trackedContext ) ;
243
+
244
+ // Completing in opposite order as created
245
+ var avmb1 = AsyncVoidMethodBuilder . Create ( ) ;
246
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
247
+ var avmb2 = AsyncVoidMethodBuilder . Create ( ) ;
248
+ Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
249
+ avmb2 . SetException ( new InvalidOperationException ( "uh oh 1" ) ) ;
250
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
251
+ avmb1 . SetException ( new InvalidCastException ( "uh oh 2" ) ) ;
252
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
253
+
254
+ Assert . Equal ( 2 , trackedContext . PostExceptions . Count ) ;
255
+ Assert . IsType < InvalidOperationException > ( trackedContext . PostExceptions [ 0 ] ) ;
256
+ Assert . IsType < InvalidCastException > ( trackedContext . PostExceptions [ 1 ] ) ;
257
+
258
+ // Completing in same order as created
259
+ var avmb3 = AsyncVoidMethodBuilder . Create ( ) ;
260
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
261
+ var avmb4 = AsyncVoidMethodBuilder . Create ( ) ;
262
+ Assert . Equal ( 2 , trackedContext . TrackedCount ) ;
263
+ avmb3 . SetException ( new InvalidOperationException ( "uh oh 3" ) ) ;
264
+ Assert . Equal ( 1 , trackedContext . TrackedCount ) ;
265
+ avmb4 . SetException ( new InvalidCastException ( "uh oh 4" ) ) ;
266
+ Assert . Equal ( 0 , trackedContext . TrackedCount ) ;
267
+
268
+ Assert . Equal ( 4 , trackedContext . PostExceptions . Count ) ;
269
+ Assert . IsType < InvalidOperationException > ( trackedContext . PostExceptions [ 2 ] ) ;
270
+ Assert . IsType < InvalidCastException > ( trackedContext . PostExceptions [ 3 ] ) ;
271
+ }
272
+ finally
273
+ {
274
+ SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
275
+ }
257
276
}
258
277
259
278
// Creating a task builder, building it, completing it faulted, and making sure it can't be reset
@@ -324,6 +343,53 @@ public static void TaskMethodBuilderT_TaskIsCached()
324
343
Assert . Same ( t1 , t2 ) ;
325
344
}
326
345
346
+ [ Fact ]
347
+ public static void TaskMethodBuilder_UsesCompletedCache ( )
348
+ {
349
+ var atmb1 = new AsyncTaskMethodBuilder ( ) ;
350
+ var atmb2 = new AsyncTaskMethodBuilder ( ) ;
351
+ atmb1 . SetResult ( ) ;
352
+ atmb2 . SetResult ( ) ;
353
+ Assert . Same ( atmb1 . Task , atmb2 . Task ) ;
354
+ }
355
+
356
+ [ Theory ]
357
+ [ InlineData ( true ) ]
358
+ [ InlineData ( false ) ]
359
+ public static void TaskMethodBuilderBoolean_UsesCompletedCache ( bool result )
360
+ {
361
+ TaskMethodBuilderT_UsesCompletedCache ( result , true ) ;
362
+ }
363
+
364
+ [ Theory ]
365
+ [ InlineData ( 0 , true ) ]
366
+ [ InlineData ( 5 , true ) ]
367
+ [ InlineData ( - 5 , false ) ]
368
+ [ InlineData ( 42 , false ) ]
369
+ public static void TaskMethodBuilderInt32_UsesCompletedCache ( int result , bool shouldBeCached )
370
+ {
371
+ TaskMethodBuilderT_UsesCompletedCache ( result , shouldBeCached ) ;
372
+ }
373
+
374
+ [ Theory ]
375
+ [ InlineData ( ( string ) null , true ) ]
376
+ [ InlineData ( "test" , false ) ]
377
+ public static void TaskMethodBuilderRef_UsesCompletedCache ( string result , bool shouldBeCached )
378
+ {
379
+ TaskMethodBuilderT_UsesCompletedCache ( result , shouldBeCached ) ;
380
+ }
381
+
382
+ private static void TaskMethodBuilderT_UsesCompletedCache < T > ( T result , bool shouldBeCached )
383
+ {
384
+ var atmb1 = new AsyncTaskMethodBuilder < T > ( ) ;
385
+ var atmb2 = new AsyncTaskMethodBuilder < T > ( ) ;
386
+
387
+ atmb1 . SetResult ( result ) ;
388
+ atmb2 . SetResult ( result ) ;
389
+
390
+ Assert . Equal ( shouldBeCached , object . ReferenceEquals ( atmb1 . Task , atmb2 . Task ) ) ;
391
+ }
392
+
327
393
[ Fact ]
328
394
public static void Tcs_ValidateFaultedTask ( )
329
395
{
@@ -355,14 +421,20 @@ public static void TaskMethodBuilderT_ValidateFaultedTask()
355
421
public static void TrackedSyncContext_ValidateException ( )
356
422
{
357
423
SynchronizationContext previousContext = SynchronizationContext . Current ;
358
- var tosc = new TrackOperationsSynchronizationContext ( ) ;
359
- SynchronizationContext . SetSynchronizationContext ( tosc ) ;
360
- var avmb = AsyncVoidMethodBuilder . Create ( ) ;
361
- try { throw new InvalidOperationException ( ) ; }
362
- catch ( Exception exc ) { avmb . SetException ( exc ) ; }
363
- Assert . NotEmpty ( tosc . PostExceptions ) ;
364
- ValidateException ( tosc . PostExceptions [ 0 ] ) ;
365
- SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
424
+ try
425
+ {
426
+ var tosc = new TrackOperationsSynchronizationContext ( ) ;
427
+ SynchronizationContext . SetSynchronizationContext ( tosc ) ;
428
+ var avmb = AsyncVoidMethodBuilder . Create ( ) ;
429
+ try { throw new InvalidOperationException ( ) ; }
430
+ catch ( Exception exc ) { avmb . SetException ( exc ) ; }
431
+ Assert . NotEmpty ( tosc . PostExceptions ) ;
432
+ ValidateException ( tosc . PostExceptions [ 0 ] ) ;
433
+ }
434
+ finally
435
+ {
436
+ SynchronizationContext . SetSynchronizationContext ( previousContext ) ;
437
+ }
366
438
}
367
439
368
440
// Running tasks with exceptions.
0 commit comments