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 &gt;= n_throughput

        static void Main(string[] args)
        {
            var tasks = new List&lt;Task&gt;();

            for (int i = 0; i &lt; m_threads; i++)
                tasks.Add(Task.Factory.StartNew(() =&gt; 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() &lt; 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. Also I should keep an eye to the completion of the tasks that are started otherwise number of pending tasks would keep increasing every second? Right.
Welcome to CR.  There is a lot of room for improvement with your code.  Let's start with the simple stuff and work our way up.

CR prefers use of braces always with if or for or foreach.

Hungarian Notation is heavily frowned upon, so get rid of names prefaced with m_.

Underscores internal to variable names are also frowned upon, so sleep_time would be better as sleepTime (or better altogether with a different name: see further below).

Names should meaningful and create clarity rather than confusion.  So m_threads isn't the number of threads running, but rather its the number of tasks you will start.  Thus that variable name should have "tasks" in it rather than "threads".

You should place your code into its own class.  For instance, class ThroughputTester.  There would be class level properties or fields named TaskCount, TargetThroughput, and TossesPerSecond.  I would not have these as constant fields, since it makes your code rigid and only applicable to the one set of values.  Rather these could be readonly properties set in the constructor, which allows for experimentation with different sets of values.

You could also have a CreateDefault method to create an instance with the same values as your constants.

public class ThroughputTester
{
    public ThroughputTester(int taskCount, int targetThroughput, int tossesPerSecond)
    {
        TaskCount = taskCount;
        TargetThroughput = targetThroughput;
        TossesPerSecond = tossesPerSecond;
    }

    public int TaskCount { get; }
    public int TargetThroughput { get; }
    public int TossesPerSecond { get; }

    public static ThroughputTester CreateDefault =&gt; new ThroughputTester(100, 2000, 2000);

}


Your use of Random is fragile and runs into issues, particularly since you have it in a method with a loop.  The better usage would be to define the Random instance at the class level instead of inside a method.

sleep_time leaves me wondering what it represents.  Is it seconds or milliseconds?  Can't tell from a vague name like time.  It could be renamed sleepMilliseconds.  Alternatively, you could use the Thread.Sleep(TimeSpan) signature (see link here) along with the TimeSpan.FromMilliseconds or TimeSpan.FromSeconds methods.

That said, even Thread.Sleep has some negativity associated with it.  You should read this answer for Why is Thread.Sleep so harmful.