I wanted to do that too and I found a nice solution by inverting the time and occurences. What does it mean:
Instead of expressing my problem as "I want N occurences per second", I inversed it as "I want 1 occurence per 1/N seconds". That way, instead of modifying the number of occurences (which will always be 1), I could easily change the time unit. I added this method to the class (you could derive too):
private object _updateTimeUnitLock = new object();
private int nextUpdateTime = 0;
public bool UpdateTimeUnit(TimeSpan timeUnit, TimeSpan dontUpdateBefore)
{
lock (_updateTimeUnitLock)
{
if ((nextUpdateTime == 0) || (nextUpdateTime <= Environment.TickCount))
{
TimeUnitMilliseconds = (int)timeUnit.TotalMilliseconds;
nextUpdateTime = Environment.TickCount + (int)dontUpdateBefore.TotalMilliseconds;
return true;
}
return false;
}
}
Mine had to be threadsafe and I needed a way to prevent changes during certain periods, so on your side you may want to remove the lock and dontUpdateBefore
param, which means you can just set TimeUnitMilliseconds and this value will be picked up at the next timer tick.
Now, to call this, you just need to calculate the new time you want based on the number of occurences you want.
Hope it could fit your needs.
Update 3/12/22: the original link to the RateGate class is broken but I found a copy of the class on Github.