-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Is your feature request related to a problem? Please describe.
Yes, it is related to the problem already described in dotnet/aspnetcore#2542, which is the fact that ChangeToken.OnChange fires more than once for a single change.
I would post this idea in that issue, but it is closed, so I had to open this new one.
Describe the solution you'd like
My solution idea, which I used in my project and worked for me, is to, instead of trying to consider only the last OnChange call, to consider only the very first call, and ignore subsequent calls by adding a "cool down period".
I am not sure if this solution is good for all cases, since I was not able to find out if the changes are guaranteed to be complete on the first call, but if that is the case, then this would solve the problem without introducing a delay on the OnChange execution.
Also, not sure if this solution would "solve this without regressing other scenarios", as was mentioned in dotnet/aspnetcore#2542 as the reason for not implementing it in the framework.
I could use some help in answering those questions :)
And, if the answers are that the change is guaranteed to be complete on the first call, and such a solution would not regress other scenarios, here is the way I implemented it in my code, and tested in aspnetcore 3.1:
public class myService{
private readonly Timer debounceTimer;
private readonly SemaphoreSlim debounceSemaphore;
public myService()
{
debounceSemaphore = new SemaphoreSlim(1);
debounceTimer = new Timer( _ => debounceSemaphore.Release());
}
private void myOnChangeMethod()
{
if (!debounceSemaphore.Wait(0))
return;
debounceTimer.Change(1000, Timeout.Infinite);
// Do actual stuff
}
}
This way, the first time the method is called, it will be able to acquire the semaphore and will run normally. Also, it will start the timer to release the semaphore only after the coolDownPeriod has passed.
Since all calls happen almost at the same time, the following calls will return for not being able to acquire the semaphore immediately.
Please let me know if the solution is not clear enough, or if I missed some important detail.
Edit: If the answer to the questions is that the solution would be good enough, I can make a generalized version of it and submit a PR. Let me know if this is the case, please.