Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

throttling when using Parallel.For

When using a single threaded loop, I was easily able to limit my messages sent per second by putting the thread to sleep (i.e. Thread.Sleep(1000/MessagesPerSecond)), easy enough... but now that I have expanded into parallel threads this no longer works correctly.

Does anyone have a suggestion how to throttle messages sent when using Parallel threads?

Parallel.For(0, NumberOfMessages, delegate(int i) {

   // Code here

   if (MessagesPerSecond != 0)
      Thread.Sleep(1000/MessagesPerSecond);
});
like image 584
Ryan Avatar asked Dec 05 '25 07:12

Ryan


1 Answers

Use an AutoResetEvent and a timer. Whenever the timer fires, have it Set the AutoResetEvent.

Then have your process that sends messages WaitOne on the AutoResetEvent immediately before sending.

    private static readonly AutoResetEvent _Next = new AutoResetEvent(true);
    private static Timer _NextTimer;

    private static void SendMessages(IEnumerable<Message> messages)
    {
        if (_NextTimer == null)
            InitializeTimer();

        Parallel.ForEach(
            messages,
            m =>
            {
                _Next.WaitOne();
                // Do something
            }
            );
    }

    private static void SetNext(object state)
    {
        _Next.Set();
    }
like image 81
Toby Avatar answered Dec 07 '25 20:12

Toby