异步任务的有效速率限制(每个时间间隔执行N次)

本文关键字:时间 执行 有效 任务 速率 异步 | 更新日期: 2023-09-27 18:29:58

使用.Net 4.0/4.5任务时,如何实现高效的速率限制算法(每个时间间隔执行N次特定操作)?例如,如果一秒钟内发送了N条以上的消息,我希望SendMessageAsync阻止(不发送另一条消息)。

        await Task.WhenAll(
                    Enumerable.Range(0, TOTAL_MESSAGES)
                    .Select(async x =>
                    {
                        await clientSession.SendMessageAsync(CreateMessage());
                    }));

我曾尝试在SendMessageAsync中使用Task.Delay,但由于等待Task.Delay立即返回,因此将在没有任何阻塞的情况下发送下一条消息。

public async Task<ResponseMessage> SendMessageAsync(RequestMessage message)
{
    int sleepTime;
    if (throttler.ShouldThrottle(out sleepTime))
    {
        await Task.Delay(sleepTime);
    }
    return await InternalMessageWithoutWaitingAsync(message);
}

我可以将await Task.Delay(sleepTime)更改为Thread.Sleep(sleepTime),从而在异步之前等待,但我想知道在使用Tasks时这是否是一个好的做法。

异步任务的有效速率限制(每个时间间隔执行N次)

async代码中使用Thread.Sleep不是一个好的做法。

你可能会得到你需要的东西:

private SemaphoreSlim _semaphore = new SemaphoreSlim(N);
public async Task<ResponseMessage> SendMessageAsync(RequestMessage message)
{
  await _semaphore.WaitAsync();
  try
  {
    return await InternalMessageWithoutWaitingAsync(message);
  }
  finally
  {
    ReleaseSemaphoreAfterDelayAsync();
  }
}
private async Task ReleaseSemaphoreAfterDelayAsync()
{
  await Task.Delay(TimeInterval);
  _semaphore.Release();
}