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