7
7
using System . Runtime . CompilerServices ;
8
8
using System . Threading ;
9
9
using System . Threading . Tasks ;
10
+ using Microsoft . Extensions . Internal ;
10
11
11
12
namespace Microsoft . AspNetCore . Internal
12
13
{
@@ -19,9 +20,9 @@ internal class TimerAwaitable : IDisposable, ICriticalNotifyCompletion
19
20
private readonly TimeSpan _period ;
20
21
21
22
private readonly TimeSpan _dueTime ;
23
+ private readonly object _lockObj = new object ( ) ;
22
24
private bool _disposed ;
23
25
private bool _running = true ;
24
- private object _lockObj = new object ( ) ;
25
26
26
27
public TimerAwaitable ( TimeSpan dueTime , TimeSpan period )
27
28
{
@@ -42,39 +43,20 @@ public void Start()
42
43
43
44
if ( _timer == null )
44
45
{
45
- // Don't capture the current ExecutionContext and its AsyncLocals onto the timer
46
- bool restoreFlow = false ;
47
- try
46
+ // This fixes the cycle by using a WeakReference to the state object. The object graph now looks like this:
47
+ // Timer -> TimerHolder -> TimerQueueTimer -> WeakReference<TimerAwaitable> -> Timer -> ...
48
+ // If TimerAwaitable falls out of scope, the timer should be released.
49
+ _timer = NonCapturingTimer . Create ( state =>
48
50
{
49
- if ( ! ExecutionContext . IsFlowSuppressed ( ) )
51
+ var weakRef = ( WeakReference < TimerAwaitable > ) state ! ;
52
+ if ( weakRef . TryGetTarget ( out var thisRef ) )
50
53
{
51
- ExecutionContext . SuppressFlow ( ) ;
52
- restoreFlow = true ;
54
+ thisRef . Tick ( ) ;
53
55
}
54
-
55
- // This fixes the cycle by using a WeakReference to the state object. The object graph now looks like this:
56
- // Timer -> TimerHolder -> TimerQueueTimer -> WeakReference<TimerAwaitable> -> Timer -> ...
57
- // If TimerAwaitable falls out of scope, the timer should be released.
58
- _timer = new Timer ( state =>
59
- {
60
- var weakRef = ( WeakReference < TimerAwaitable > ) state ! ;
61
- if ( weakRef . TryGetTarget ( out var thisRef ) )
62
- {
63
- thisRef . Tick ( ) ;
64
- }
65
- } ,
66
- new WeakReference < TimerAwaitable > ( this ) ,
67
- _dueTime ,
68
- _period ) ;
69
- }
70
- finally
71
- {
72
- // Restore the current ExecutionContext
73
- if ( restoreFlow )
74
- {
75
- ExecutionContext . RestoreFlow ( ) ;
76
- }
77
- }
56
+ } ,
57
+ state : new WeakReference < TimerAwaitable > ( this ) ,
58
+ dueTime : _dueTime ,
59
+ period : _period ) ;
78
60
}
79
61
}
80
62
}
0 commit comments