You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// The code in this file is based on the following source,
2
+
// which is licensed to the .NET Foundation under one or more agreements.
3
+
// Original code: https://github.com/dotnet/runtime/blob/0096ba52e8c86e4d712013f6330a9b8a6496a1e0/src/libraries/System.Private.CoreLib/src/System/Threading/PeriodicTimer.cs
/// <summary>Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the <see cref="PeriodicTimer" /> object.</summary>
61
+
~ManualPeriodicTimer()=>Dispose();
62
+
63
+
/// <summary>Core implementation for the periodic timer.</summary>
64
+
[SuppressMessage("Reliability","CA2002:Do not lock on objects with weak identity",Justification="Code copied from Microsoft.")]
/// <summary>Cancellation registration for any active <see cref="WaitForNextTickAsync"/> call.</summary>
91
+
privateCancellationTokenRegistration_ctr;
92
+
/// <summary>Whether the timer has been stopped.</summary>
93
+
privatebool_stopped;
94
+
/// <summary>Whether there's a pending notification to be received. This could be due to the timer firing, the timer being stopped, or cancellation being requested.</summary>
95
+
privatebool_signaled;
96
+
/// <summary>Whether there's a <see cref="WaitForNextTickAsync"/> call in flight.</summary>
97
+
privatebool_activeWait;
36
98
37
-
if(!stopped&&completionSourceis not null)
99
+
/// <summary>Wait for the next tick of the timer, or for the timer to be stopped.</summary>
// Dispose of the cancellation registration. This is done outside of the below lock in order
179
+
// to avoid a potential deadlock due to waiting for a concurrent cancellation callback that might
180
+
// in turn try to take the lock. For valid usage, GetResult is only called once _ctr has been
181
+
// successfully initialized before WaitForNextTickAsync returns to its synchronous caller, and
182
+
// there should be no race conditions accessing it, as concurrent consumption is invalid. If there
183
+
// is invalid usage, with GetResult used erroneously/concurrently, the worst that happens is cancellation
184
+
// may not take effect for the in-flight operation, with its registration erroneously disposed.
185
+
// Note we use Dispose rather than Unregister (which wouldn't risk deadlock) so that we know that thecancellation callback associated with this operation
186
+
// won't potentially still fire after we've completed this GetResult and a new operation
Copy file name to clipboardExpand all lines: src/TimeProviderExtensions/System.Threading/TimeProviderPeriodicTimerExtensions.cs
+5-1Lines changed: 5 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,11 @@ public static class TimeProviderPeriodicTimerExtensions
15
15
/// may be in flight at any given moment. <see cref="System.Threading.PeriodicTimer.Dispose()"/> may be used concurrently with an active <see cref="System.Threading.PeriodicTimer.WaitForNextTickAsync"/>
16
16
/// to interrupt it and cause it to return false.
17
17
/// </remarks>
18
-
/// <returns>A new <see cref="TimeProviderExtensions.PeriodicTimer"/>. Note, this is a wrapper around a <see cref="System.Threading.PeriodicTimer"/>.</returns>
18
+
/// <returns>
19
+
/// A new <see cref="TimeProviderExtensions.PeriodicTimer"/>.
20
+
/// Note, this is a wrapper around a <see cref="System.Threading.PeriodicTimer"/>,
21
+
/// and will behave exactly the same as the original.
0 commit comments