2013-05-31 230 views
0

我在写一个Windows Store应用程序,它将依赖于JSON api。 API的提供者要求每秒不超过1个API请求。每秒执行一次任务的最佳方式是什么?

所以我创建了一个类,让我来排队的阻隔队列中的请求,并在后台线程它会运行一个循环,如下所示:

Loop 
{ 
// this will block until a request is added to the queue 
MyRequest = Queue.Take() 

// Create task to make the api request here. 

Thread.Sleep(1000) 
} 

通过这种方式,它会等待在尝试将另一个请求出队之前至少还有一秒。

我发现Thread.Sleep不适用于Windows应用商店。 Task.Delay()似乎不必要的浪费,因为每次调用它时都会创建一个新任务。

我觉得可能有一种已知的方式来做到这一点,我不知道?

感谢,

+0

任务非常轻量级,在.NET 4.5/Core中更是如此。 –

回答

3

我知道Task.Delay()似乎很浪费,但我们建议由微软员工和主持人的MSDN here

使用。睡眠()或无限循环一样TGH建议将导致程序在等待时变得无反应。如果你想让它在处理您的队列响应,你会使用这样的:

await Task.Delay(1000);

0

如果您希望任务在后台执行,我会建议一个System.Threading.Timer。将其设置为一次性而非周期性计时器,并在每次请求后进行刷新。例如:

System.Threading.Timer myTimer; 

// initialize timer 
myTimer = new Timer(TimerProc, null, 1000, Timeout.Infinite); 

void TimerProc(object state) 
{ 
    // do request here 
    // then reset the timer 
    myTimer.Change(1000, Timeout.Infinite); 
} 

这会在一个请求结束和下一个请求开始之间等待一秒钟。

如果您希望滴答以一秒为间隔执行,您必须确保它们不能重叠。这对Monitor来说很简单。你需要的锁定对象,并让你的计时器的周期定时器:

object timerLock = new object(); 

// initialize periodic timer 
myTimer = new Timer(TimerProc, null, 1000, 1000); 

而且你的计时器PROC:

void TimerProc(object state) 
{ 
    if (!Monitor.TryEnter(timerLock)) 
    { 
     // a request is currently being processed 
     return; 
    } 
    try 
    { 
     // do request here 
    } 
    catch (expected exceptions) 
    { 
    } 
    Monitor.Exit(timerLock); 
} 

请注意,我没有在finallyMonitor.Exit。有关原因,请参阅Eric Lippert的Locks and exceptions do not mix

相关问题