performance – Rate limit a method by generating particular load on demand in C#


I am working on a project where I want to generate random throughput on a particular method so that I can do some performance testing on it. This way I can test my method by generating random throughputs and see how my method works under all those scenarios.

For example: I need to call my doIOStuff method at an approximate rate of x requests per second from multiple threads where x will be less than 2000 mostly but it really doesn’t matter in this case. It doesn’t have to be accurate so there is some room for an error but the overall idea is I need to make sure that my method doIOStuff is executed no more than x times in a sliding window of y seconds.

Assuming we start n threads and want a maximum of m calls per second. We can achieve this by having each thread generate a random number between 0 and 1, k times per second and call doIOStuff method only if the generated number is less than m / n / k.

Below is the code I got which uses global variables and it does the job but I think it can be improved a lot where I can use some cancellation tokens as well and make it more efficient and clean.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;


namespace ConsoleApp
{
    class Program
    {
        const int m_threads = 100;
        const int n_throughput = 2000;
        const int k_toss_per_second = 2000; // Note that k_toss_per_second x  m_threads >= n_throughput

        static void Main(string() args)
        {
            var tasks = new List<Task>();

            for (int i = 0; i < m_threads; i++)
                tasks.Add(Task.Factory.StartNew(() => doIOStuff()));

            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("All threads complete");
        }


        static void callDoIOStuff()
        {
           int sleep_time = (int) (1000 * 1.0d / k_toss_per_second);
           double threshold = (double) n_throughput / m_threads / k_toss_per_second; 
           Random random = new Random();
           while (true) {
                Thread.Sleep(sleep_time);
                if (random.NextDouble() < threshold)
                    doIOStuff();
            }
        }

        static void doIOStuff()
        {
            // do some IO work
        }
    }
}

I wanted to see what can we do here to make it more efficient and clean so that it can used in production testing for generating random throughput load.