C# Round Robin Resources
The Problem:
You have scarce / limited resources and you want to use these in and efficient way in your Code. E.g. You can only create N objects of certain class because of its limitation in terms of Resources or Licenses, and you want to share those Objects across M Consumers.
The Solution:
One way is to use Round Robin scheduling, and in this post I’ll show you how to do that.
Let’s say we have a class ScarceResource which can only be instantiated 3 times in a program. As an example our class generates Random numbers.
public class ScarceResource { private Random _random; private string _name; public ScarceResource(string Name) { _name = Name; _random = new Random(); } public ScarceResource(string Name, int seed) { _name = Name; _random = new Random(seed); } public string GetRandomNumber() { return _name + ":" + _random.Next().ToString(); } }
RoundRobinList class will handle Round Robin Scheduling
public class RoundRobinList{ private readonly IList _list; private readonly int _size; private int _position; private object _lock; public RoundRobinList(IList list) { if (!list.Any()) throw new NullReferenceException("list"); _list = new List (list); _size = _list.Count; _position = 0; _lock = new object(); } public T Next() { if (_size == 1) return _list[0]; lock (_lock) { if (_position == _size) { _position = 0; } return _list[_position++]; } } }
Below is a sample Console Program which instantiate 3 Objects of ScarceResource and Use these Objects in Round Robin fashion to Generate Random Numbers.
class Program { static RoundRobinListrrList; static bool keepRunning = true; static void Main(string[] args) { Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; keepRunning = false; }; // Create Objects and add to List List list = new List (); list.Add(new ScarceResource("Object 1", 8767)); list.Add(new ScarceResource("Object 2", 12323)); list.Add(new ScarceResource("Object 3", 1214)); // Create Round Robin List and Add Objects List to it rrList = new RoundRobinList (list); while (keepRunning) { Process(); System.Threading.Thread.Sleep(1000); } } public static async Task Process() { await Task.Run(() => Console.WriteLine(rrList.Next().GetRandomNumber())); } }