@@ -80,14 +80,12 @@ public async Task SimultaneousAccessIsSerialized()
8080 {
8181 Value = 1 ,
8282 Name = "Request1" ,
83- CompletionSource = new ( ) ,
8483 } ;
8584
8685 var request2 = new DelayGetValue . Query ( )
8786 {
8887 Value = 1 ,
8988 Name = "Request2" ,
90- CompletionSource = new ( ) ,
9189 } ;
9290
9391 var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
@@ -102,7 +100,7 @@ public async Task SimultaneousAccessIsSerialized()
102100 Assert . Equal ( 0 , request2 . TimesExecuted ) ;
103101
104102 // request2 does nothing at this point
105- request2 . CompletionSource . SetResult ( ) ;
103+ request2 . WaitForTestToContinueOperation . SetResult ( ) ;
106104
107105 Assert . False ( response1Task . IsCompleted ) ;
108106 Assert . False ( response2Task . IsCompleted ) ;
@@ -111,7 +109,7 @@ public async Task SimultaneousAccessIsSerialized()
111109 Assert . Equal ( 0 , request2 . TimesExecuted ) ;
112110
113111 // trigger request1, which should run exactly once
114- request1 . CompletionSource . SetResult ( ) ;
112+ request1 . WaitForTestToContinueOperation . SetResult ( ) ;
115113
116114 var response1 = await response1Task ;
117115 var response2 = await response2Task ;
@@ -130,7 +128,6 @@ public async Task ProperlyUsesCancellationToken()
130128 {
131129 Value = 1 ,
132130 Name = "Request1" ,
133- CompletionSource = new ( ) ,
134131 } ;
135132
136133 using var tcs = new CancellationTokenSource ( ) ;
@@ -144,14 +141,13 @@ public async Task ProperlyUsesCancellationToken()
144141 Assert . False ( request . CancellationToken . IsCancellationRequested ) ;
145142
146143 // actual handler will continue executing in spite of no remaining callers
147- request . CompletionSource . SetResult ( ) ;
144+ request . WaitForTestToContinueOperation . SetResult ( ) ;
148145
149146 // check that value is now properly in cache
150147 var request2 = new DelayGetValue . Query ( )
151148 {
152149 Value = 1 ,
153150 Name = "Request2" ,
154- CompletionSource = new ( ) ,
155151 } ;
156152
157153 var response = await cache . GetValue ( request2 ) ;
@@ -168,15 +164,13 @@ public async Task CancellingFirstAccessOperatesCorrectly()
168164 {
169165 Value = 1 ,
170166 Name = "Request1" ,
171- CompletionSource = new ( ) ,
172167 } ;
173168
174169 using var cts2 = new CancellationTokenSource ( ) ;
175170 var request2 = new DelayGetValue . Query ( )
176171 {
177172 Value = 1 ,
178173 Name = "Request2" ,
179- CompletionSource = new ( ) ,
180174 } ;
181175
182176 var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
@@ -210,15 +204,13 @@ public async Task CancellingSecondAccessOperatesCorrectly()
210204 {
211205 Value = 1 ,
212206 Name = "Request1" ,
213- CompletionSource = new ( ) ,
214207 } ;
215208
216209 using var cts2 = new CancellationTokenSource ( ) ;
217210 var request2 = new DelayGetValue . Query ( )
218211 {
219212 Value = 1 ,
220213 Name = "Request2" ,
221- CompletionSource = new ( ) ,
222214 } ;
223215
224216 var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
@@ -251,19 +243,18 @@ public async Task RemovingValueCancelsExistingOperation()
251243 {
252244 Value = 1 ,
253245 Name = "Request1" ,
254- CompletionSource = new ( ) ,
255246 } ;
256247
257248 using var tcs = new CancellationTokenSource ( ) ;
258249 var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
259250 var responseTask = cache . GetValue ( request , tcs . Token ) ;
260251
261- cache . RemoveValue ( request ) ;
252+ await request . WaitForTestToStartExecuting . Task ;
262253
263- // allow IC task to be run
264- await Task . Delay ( 10 ) ;
254+ cache . RemoveValue ( request ) ;
255+ await request . WaitForTestToFinalize . Task ;
265256
266- request . CompletionSource . SetResult ( ) ;
257+ request . WaitForTestToContinueOperation . SetResult ( ) ;
267258
268259 var response = await responseTask ;
269260
@@ -281,22 +272,39 @@ public async Task SettingValueCancelsExistingOperation()
281272 {
282273 Value = 1 ,
283274 Name = "Request1" ,
284- CompletionSource = new ( ) ,
285275 } ;
286276
287277 var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
288278 var responseTask = cache . GetValue ( request , default ) ;
289279
290- // allow IC task to be run
291- await Task . Delay ( 10 ) ;
280+ await request . WaitForTestToStartExecuting . Task ;
292281
293282 cache . SetValue ( request , new ( 5 , ExecutedHandler : false , Guid . NewGuid ( ) ) ) ;
294283
295284 var response = await responseTask ;
296285 Assert . Equal ( 5 , response . Value ) ;
297286 Assert . False ( response . ExecutedHandler ) ;
298287
288+ await request . WaitForTestToFinalize . Task ;
289+
299290 Assert . Equal ( 0 , request . TimesExecuted ) ;
300291 Assert . Equal ( 1 , request . TimesCancelled ) ;
301292 }
293+
294+ [ Test ]
295+ public async Task ExceptionGetsPropagatedCorrectly ( )
296+ {
297+ var request = new DelayGetValue . Query ( )
298+ {
299+ Value = 1 ,
300+ Name = "Request1" ,
301+ ThrowException = true ,
302+ } ;
303+
304+ var cache = _serviceProvider . GetRequiredService < DelayGetValueCache > ( ) ;
305+ var responseTask = cache . GetValue ( request , default ) ;
306+
307+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await responseTask ) ;
308+ Assert . Equal ( "Test Exception 1" , ex . Message ) ;
309+ }
302310}
0 commit comments