How should I increment a number for a round robin threading scenario with least contention?
c#, interlocked, multithreading
Solution
The trick is to do the operation in a loop until it is successful. I provide a general template for this approach in my answer here.
public int GetNextNumber()
{
int initial, computed;
do
{
initial = _lastNumber;
computed = initial + 1;
computed = computed > _maxNumbers ? computed = 1 : computed;
}
while (Interlocked.CompareExchange(ref _lastNumber, computed, initial) != initial);
return computed;
}
Problem
If many threads are calling `GetNextNumber` simultaneously with the following code, `GetNextNumber` will return 1 more times than any other numbers. ``` private class RoundRobbinNumber { private int _maxNumbers = 10; private int _lastNumber; private RoundRobbinNumber(int maxNumbers) { _maxNumbers = maxNumbers; } public int GetNextNumber() { int nextNumber = Interlocked.Increment(ref _lastNumber); if (_lastNumber > _maxNumbers) { Interlocked.CompareExchange(ref _lastNumber, 1, _maxNumbers); nextNumber = 1; } return nextNumber; } } ``` Is there a way to reset the `_lastNumber` back to one, and reliably return an incremented number for each thread calling `GetNextNumber()`, without having to use a lock?