I want to call a method after some delay when an event is raised, but any subsequent events should "restart" this delay. Quick example to illustrate, the view should be updated when scrollbar position changes, but only 1 second after the user has finished scrolling.
Now I can see many ways of implementing that, but the most intuitive would be to use Task.Delay
+ ContinueWith
+ cancellation token. However, I am experiencing some issues, more precisely subsequent calls to my function cause the TaskCanceledException
exception and I started to wonder how I could get rid of that. Here is my code:
private CancellationTokenSource? _cts;
private async void Update()
{
_cts?.Cancel();
_cts = new();
await Task.Delay(TimeSpan.FromSeconds(1), _cts.Token)
.ContinueWith(o => Debug.WriteLine("Update now!"),
TaskContinuationOptions.OnlyOnRanToCompletion);
}
I have found a workaround that works pretty nicely, but I would like to make the first idea work.
private CancellationTokenSource? _cts;
private CancellationTokenRegistration? _cancellationTokenRegistration;
private void Update()
{
_cancellationTokenRegistration?.Unregister();
_cts = new();
_cancellationTokenRegistration = _cts.Token.Register(() => Debug.WriteLine("Update now!"));
_cts.CancelAfter(1000);
}