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

当使用.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);
}

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

最佳答案 在异步代码中使用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();
}
点赞