一秒钟不超过一次执行一项任务的最佳方法是什么?

本文关键字:最佳 方法 是什么 任务 执行 不超过 一次 一秒钟 一项 | 更新日期: 2023-09-27 18:16:05

我正在编写一个依赖于JSON api的Windows Store应用程序。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)
}

这样,它将至少等待一秒钟,然后再尝试将另一个请求从队列中取出。

我已经找到了那个线程。windows商店的应用程序不支持Sleep。task . delay()似乎不必要地浪费,因为每次调用它都会创建一个新任务。

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

谢谢,

一秒钟不超过一次执行一项任务的最佳方法是什么?

我知道Task.Delay()似乎很浪费,但这是微软员工和MSDN版主在这里推荐的

使用. sleep()或像TGH建议的无限循环会导致程序在等待时变得无响应。如果您希望它在处理队列时响应,您可以使用如下内容:

await Task.Delay(1000);

如果你想让任务在后台执行,我建议使用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);
}

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

如果你想让tick每隔一秒执行一次,你必须确保它们不会重叠。这对Monitor来说很简单。您将需要一个锁对象,并将计时器设置为周期计时器:

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

和你的定时器进程:

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

注意,我没有在finally中做Monitor.Exit。参见Eric Lippert的《锁和异常不能混在一起》