@@ -15,15 +15,25 @@ public static class TimeProviderTaskExtensions
15
15
#if ! NET8_0_OR_GREATER
16
16
private sealed class DelayState : TaskCompletionSource < bool >
17
17
{
18
- public DelayState ( ) : base ( TaskCreationOptions . RunContinuationsAsynchronously ) { }
19
- public ITimer Timer { get ; set ; }
18
+ public DelayState ( CancellationToken cancellationToken ) : base ( TaskCreationOptions . RunContinuationsAsynchronously )
19
+ {
20
+ CancellationToken = cancellationToken ;
21
+ }
22
+
23
+ public ITimer ? Timer { get ; set ; }
24
+ public CancellationToken CancellationToken { get ; }
20
25
public CancellationTokenRegistration Registration { get ; set ; }
21
26
}
22
27
23
28
private sealed class WaitAsyncState : TaskCompletionSource < bool >
24
29
{
25
- public WaitAsyncState ( ) : base ( TaskCreationOptions . RunContinuationsAsynchronously ) { }
30
+ public WaitAsyncState ( CancellationToken cancellationToken ) : base ( TaskCreationOptions . RunContinuationsAsynchronously )
31
+ {
32
+ CancellationToken = cancellationToken ;
33
+ }
34
+
26
35
public readonly CancellationTokenSource ContinuationCancellation = new CancellationTokenSource ( ) ;
36
+ public CancellationToken CancellationToken { get ; }
27
37
public CancellationTokenRegistration Registration ;
28
38
public ITimer ? Timer ;
29
39
}
@@ -66,22 +76,22 @@ public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, Cancell
66
76
return Task . FromCanceled ( cancellationToken ) ;
67
77
}
68
78
69
- DelayState state = new ( ) ;
79
+ DelayState state = new ( cancellationToken ) ;
70
80
71
- state . Timer = timeProvider . CreateTimer ( delayState =>
81
+ state . Timer = timeProvider . CreateTimer ( static delayState =>
72
82
{
73
83
DelayState s = ( DelayState ) delayState ! ;
74
84
s . TrySetResult ( true ) ;
75
85
s . Registration . Dispose ( ) ;
76
- s ? . Timer . Dispose ( ) ;
86
+ s . Timer ? . Dispose ( ) ;
77
87
} , state , delay , Timeout . InfiniteTimeSpan ) ;
78
88
79
- state . Registration = cancellationToken . Register ( delayState =>
89
+ state . Registration = cancellationToken . Register ( static delayState =>
80
90
{
81
91
DelayState s = ( DelayState ) delayState ! ;
82
- s . TrySetCanceled ( cancellationToken ) ;
92
+ s . TrySetCanceled ( s . CancellationToken ) ;
83
93
s . Registration . Dispose ( ) ;
84
- s ? . Timer . Dispose ( ) ;
94
+ s . Timer ? . Dispose ( ) ;
85
95
} , state ) ;
86
96
87
97
// There are race conditions where the timer fires after we have attached the cancellation callback but before the
@@ -153,7 +163,7 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time
153
163
return Task . FromCanceled ( cancellationToken ) ;
154
164
}
155
165
156
- var state = new WaitAsyncState ( ) ;
166
+ WaitAsyncState state = new ( cancellationToken ) ;
157
167
158
168
state . Timer = timeProvider . CreateTimer ( static s =>
159
169
{
@@ -162,7 +172,7 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time
162
172
state . TrySetException ( new TimeoutException ( ) ) ;
163
173
164
174
state . Registration . Dispose ( ) ;
165
- state . Timer ! . Dispose ( ) ;
175
+ state . Timer ? . Dispose ( ) ;
166
176
state . ContinuationCancellation . Cancel ( ) ;
167
177
} , state , timeout , Timeout . InfiniteTimeSpan ) ;
168
178
@@ -182,7 +192,7 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time
182
192
{
183
193
var state = ( WaitAsyncState ) s ! ;
184
194
185
- state . TrySetCanceled ( ) ;
195
+ state . TrySetCanceled ( state . CancellationToken ) ;
186
196
187
197
state . Timer ? . Dispose ( ) ;
188
198
state . ContinuationCancellation . Cancel ( ) ;
@@ -259,16 +269,16 @@ public static CancellationTokenSource CreateCancellationTokenSource(this TimePro
259
269
260
270
var cts = new CancellationTokenSource ( ) ;
261
271
262
- ITimer timer = timeProvider . CreateTimer ( s =>
272
+ ITimer timer = timeProvider . CreateTimer ( static s =>
263
273
{
264
274
try
265
275
{
266
- ( ( CancellationTokenSource ) s ) . Cancel ( ) ;
276
+ ( ( CancellationTokenSource ) s ! ) . Cancel ( ) ;
267
277
}
268
278
catch ( ObjectDisposedException ) { }
269
279
} , cts , delay , Timeout . InfiniteTimeSpan ) ;
270
280
271
- cts . Token . Register ( t => ( ( ITimer ) t ) . Dispose ( ) , timer ) ;
281
+ cts . Token . Register ( static t => ( ( ITimer ) t ! ) . Dispose ( ) , timer ) ;
272
282
return cts ;
273
283
#endif // NET8_0_OR_GREATER
274
284
}
0 commit comments