如何每200毫秒只执行一次任务

时间:2014-05-07 18:09:15

标签: c# wcf .net-4.0

我需要在for循环中向webserver发布25个请求。由于某种原因,网络服务器每秒仅限5次呼叫。所以我需要确保自上次请求以来已经过了200毫秒。我将下面的代码作为演示(实际代码在WCF服务中),但我相信Thread.Sleep不是最好的方法。有没有其他选择,Theaded或其他?

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);
    }
}

1 个答案:

答案 0 :(得分:2)

鉴于这是一个控制台应用程序,Thread.Sleep()实际上可以很好地工作。它会阻塞,但是当阻塞时,确实没有任何其他工作要做,所以有一些缺点。

如果这是一个GUI应用程序,服务或阻塞不好的其他场景,那么我建议使用异步方法,而await Task.Delay(pause)代替,这将允许UI继续处理消息。但是,这在控制台应用程序中无关紧要,因此您当前的方法几乎没有任何缺点。

这将涉及使您的主要方法异步

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);
     }
}

请注意,PostData不再需要任何与阻止相关的逻辑 - 它只会发布您的相关数据。

这可能有可能在.NET 4中完成任务延续,但我可能只是使用Sleep因为逻辑变得相当丑陋,非常快。