Question

I need to post ie 25 requests to webserver in a for loop. The webserver is limited to only 5 calls per second for some reason. So I need to make sure 200 miliseconds have passed since the last request. I have this code below as a demo (the actual code is inside a WCF service), but I believe Thread.Sleep is not the best way to go. Are there any alternatives, Theaded or otherwise?

class Program
{
    private static long lastRun = DateTime.Now.Ticks;

    static void Main(string[] args)
    {
        for (int i = 0; i < 25; i++) { PostData(); }

        Console.WriteLine("Hit any key...");
        Console.ReadLine();
    }

    static void PostData()
    {
        var elapsedMilliseconds = (int)TimeSpan.FromTicks(DateTime.Now.Ticks - lastRun).TotalMillliseconds;

        if (elapsedMilliseconds < 200)
        {
            var pause = 200 - elapsedMilliseconds;
            Console.WriteLine("Pausing for " + pause);

            // pause
            Thread.Sleep(pause);
        }
// HttpPost here

        lastRun = DateTime.Now.Ticks;
        Console.WriteLine("Job done at {0}.{1}", DateTime.Now, DateTime.Now.Millisecond);
    }
}
Was it helpful?

Solution

Given that this is a console application, Thread.Sleep() will actually work quite well. It blocks, but there really isn't any other work to be done while this is blocking, so there's little downsides.

If this were a GUI app, service, or other scenario where blocking is bad, however, then I would recommend using asynchronous methods, and await Task.Delay(pause) instead, which would allow the UI to continue processing messages. This doesn't matter in a console application, though, so there is little or no downside to your current approach.

This would involve making your main method asynchrnous

static async Task PostDataMultipleTimes(int times)
{
     for (int i=0;i<times;++i)
     {
         var sw = Stopwatch.StartNew();
         PostData(); // PostData doesn't need to sleep/wait/etc anymore

         var ms = (int)sw.ElapsedMilliseconds;
         if (ms < 200)
             await Task.Delay(200 - ms);
     }
}

Note that PostData no longer needs any logic related to blocking - it would just post your relevant data.

This would likely be possible to accomplish in .NET 4. with task continuations, but I'd likely just use Sleep as the logic gets fairly ugly, very quickly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top