ProbabilisticTrigger
Namespace: SnowBank.Threading · class
Helps decide whether to trigger some process or postpone to the next opportunity, with some adjustable probabilities
Remarks
This rolls a virtual dice that will, on average, returns true after a certain number of attempts, with enforced minimum and maximum.
Let's say, for example, that you need to perform some cleanup operation on average every 50 iterations, but never before 20 iterations or after 100 iterations. When calling RollDice repeatedly, you should observe a run at least 20 consecutive false results, with the first true result happening (on average) before the 50th call, and never after the 100th call.
This type is not thread-safe, and requires external locking if shared between multiple threads.
// trigger on average every 50 calls, never before 10, always before 100 var trigger = new ProbabilisticTrigger(Random.Shared, 0.1, 10, 50, 100); source.OnChanged((...) => { // process the event... // maybe kick off some cleaning operation if (trigger.RollDice()) { await PerformCleanupOperation(...); trigger.Reset(); // reset the trigger! } });
Constructors
ProbabilisticTrigger
ProbabilisticTrigger(Random rng, double steepness, int minimum, int median, int? maximum)
Properties
Attempts
int Attempts { get; }
Number of calls to RollDice since the last call to Reset
Maximum
int? Maximum { get; }
Maximum number of failed attempts before a forced trigger (if non-null).
Median
int Median { get; }
Median number of attempts before the first trigger.
This represents the "center point" where half of the players would have triggered at least once.
Minimum
int Minimum { get; }
Minimum number of attempts before we are allowed to trigger.
Rng
Random Rng { get; }
Random generator used to resolve the probabilities
Steepness
double Steepness { get; }
Factor (0 < k <= 1.0) used to smooth the probability distribution curve. Lower means smoother.
Triggered
bool Triggered { get; }
Sets to true whenever RollDice returns true, and reset to false whenever Reset is called.
Methods
Reset
void Reset()
Resets the internal Attempts to 0, before starting a new session.
RollDice
bool RollDice()
Rolls the dice again, to device whether to perform some action immediately or wait for the next opportunity.
Returns: true if the action should be performed immediately; or false if it should be delayed.
Calling this method will increment the internal Attempts, which can be used to infer the number of attempts since the last call to Reset.
Whenever the method returns true, you should call Reset in order to start a new run, otherwise the trigger will assume that the attempt failed.
static bool RollDice(Random rng, int iteration, double k, int minimum, int median, int? maximum)
Rolls the dice, to device whether to perform some operation or wait for the next opportunity.
rng— Random number generatoriteration— Current attempt number, starting at 1k— Coefficient used to "smooth" the internal probability distribution curve, in the range0<k<1.0. Lower values giving more spread out probabilities around the center point. Recommended values are between 0.05 and 0.2minimum— Minimum number of attempts before the operation is allowed to execute. The method will always returnfalseifiterationis less than the minimum.median— Number of rolls required to have 50% chances to trigger at least once. If you have multiple actors, all repeatedly calling this method until it returns true, half of them should have stopped before reaching this point and half of them should still be in the race.maximum— Maximum number of attempts before the operation is guaranteed to execute. The method will always returntrueifiterationis greater than or equal to this value. Ifnull, there is no maximum, and it is possible (even though extremely unlikely) that this method returnsfalseforever.