4

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

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

我尝试过使用Task.Delayinside SendMessageAsync,但由于等待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)

4

1 回答 1

2

在代码中使用Thread.Sleep不是一个好习惯。async

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

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();
}
于 2013-12-31T05:26:17.227 回答