异步任务的有效速率限制(每个时间间隔执行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时这是否是一个好的做法。
在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();
}