diff --git a/src/System.Waf/System.Waf/System.Waf.Core/Foundation/ThrottledAction.cs b/src/System.Waf/System.Waf/System.Waf.Core/Foundation/ThrottledAction.cs
index eb8747b6..dfcf9fba 100644
--- a/src/System.Waf/System.Waf/System.Waf.Core/Foundation/ThrottledAction.cs
+++ b/src/System.Waf/System.Waf/System.Waf.Core/Foundation/ThrottledAction.cs
@@ -23,7 +23,6 @@ public enum ThrottledActionMode
public class ThrottledAction
{
private readonly TaskScheduler taskScheduler;
- private readonly object cancellationTokenSourceLock = new object();
private readonly Action action;
private readonly ThrottledActionMode mode;
private readonly TimeSpan delayTime;
@@ -44,50 +43,42 @@ public ThrottledAction(Action action)
/// The argument action must not be null.
public ThrottledAction(Action action, ThrottledActionMode mode, TimeSpan delayTime)
{
- taskScheduler = SynchronizationContext.Current != null ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Default;
+ taskScheduler = SynchronizationContext.Current is not null ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Default;
this.action = action ?? throw new ArgumentNullException(nameof(action));
this.mode = mode;
this.delayTime = delayTime;
}
/// Indicates that an execution of the action delegate is requested.
- public bool IsRunning => cancellationTokenSource != null;
+ public bool IsRunning => cancellationTokenSource is not null;
/// Requests the execution of the action delegate.
public void InvokeAccumulated()
{
- CancellationToken? token = null;
- lock (cancellationTokenSourceLock)
- {
- if (mode == ThrottledActionMode.InvokeOnlyIfIdleForDelayTime || cancellationTokenSource == null)
- {
- cancellationTokenSource?.Cancel();
- cancellationTokenSource = new CancellationTokenSource();
- token = cancellationTokenSource.Token;
- }
- }
+ if (mode is not ThrottledActionMode.InvokeOnlyIfIdleForDelayTime && cancellationTokenSource is not null) return;
- if (token != null)
+ var cts = new CancellationTokenSource();
+ if (mode is ThrottledActionMode.InvokeOnlyIfIdleForDelayTime)
+ {
+ Interlocked.Exchange(ref cancellationTokenSource, cts)?.Cancel();
+ }
+ else // mode is InvokeMaxEveryDelayTime
{
- Task.Delay(delayTime, token.Value).ContinueWith(t =>
- {
- lock (cancellationTokenSourceLock)
- {
- cancellationTokenSource = null;
- }
- TaskHelper.Run(action, taskScheduler);
- }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
+ var old = Interlocked.CompareExchange(ref cancellationTokenSource, cts, null);
+ if (old is not null) return;
}
+
+ Task.Delay(delayTime, cts.Token).ContinueWith(t =>
+ {
+ Interlocked.Exchange(ref cancellationTokenSource, null);
+ TaskHelper.Run(action, taskScheduler);
+ }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
}
/// Cancel the execution of the action delegate that was requested.
public void Cancel()
{
- lock (cancellationTokenSourceLock)
- {
- cancellationTokenSource?.Cancel();
- cancellationTokenSource = null;
- }
+ Interlocked.Exchange(ref cancellationTokenSource, null)?.Cancel();
}
}
}