当使用.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)
,然后等待再执行异步操作,但是我想知道在使用任务时这是否是一个好的实践。
async
。 - Stephen ClearyThread.Sleep
绝对是一种不好的做法(浪费资源)。我没有理解你关于下一个消息将被发送而没有任何阻塞
的担忧。这是否意味着您需要按顺序执行所有任务?如果您的情况确实很复杂,可以考虑实现自己的TaskScheduler
:如何:创建限制并发性的任务计划程序。 - outcoldmanTaskScheduler
(如果你不想使用Rx
)。 - outcoldman