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?
Andrey's answer without conditional statements:
using System;
namespace Utils
{
    public class RoundRobinCounter
    {
        private int _max;
        private int _currentNumber = 0;
        public RoundRobinCounter(int max)
        {
            _max = max;
        }
        public int GetNext()
        {
            uint nextNumber = unchecked((uint)System.Threading.Interlocked.Increment(ref _currentNumber));
            int result = (int)(nextNumber % _max);
            return result;
        }
    }
}
And here is a .net fiddle running this code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With