我需要在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);
}
}
答案 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
因为逻辑变得相当丑陋,非常快。