Sup*_*JMN 4 .net c# concurrency asynchronous system.reactive
我有一个API调用,它接受每秒最大调用率.如果超过速率,则抛出异常.
我想把这个调用包装成一个抽象,它可以使调用率保持在极限之下.它将像网络路由器一样:处理多个呼叫并将结果返回给正确的呼叫者,关注呼叫率.目标是使调用代码尽可能不知道该限制.否则,具有此调用的代码中的每个部分都必须包装到try-catch中!
例如:想象一下,您可以从可以添加2个数字的extern API调用方法.此API可以每秒调用5次.高于此值的任何内容都将导致异常.
为了说明问题,限制通话费率的外部服务就像这个问题的答案中的那个
附加信息:
由于每次从代码的任何部分调用此方法时都不希望担心该限制,因此您可以考虑设计一个可以调用的包装器方法,而不必担心速率限制.在内部你关心限制,但在外面你暴露了一个简单的异步方法.
它类似于Web服务器.它如何将正确的结果包返回给正确的客户?
多个呼叫者将调用此方法,他们将在结果出现时获得结果.这种抽象应该像代理一样.
我怎么能这样做?
我确信包装方法的公司应该是这样的
public async Task<Results> MyMethod()
Run Code Online (Sandbox Code Playgroud)
在方法内部,它将执行逻辑,可能使用Reactive Extensions(Buffer).我不知道.
但是怎么样?我的意思是,多次调用此方法应该将结果返回给正确的调用者.这甚至可能吗?
非常感谢!
有速率限制库可用(参见Esendex的TokenBucket Github或Nuget).
用法非常简单,此示例将轮询限制为1秒
// Create a token bucket with a capacity of 1 token that refills at a fixed interval of 1 token/sec.
ITokenBucket bucket = TokenBuckets.Construct()
.WithCapacity(1)
.WithFixedIntervalRefillStrategy(1, TimeSpan.FromSeconds(1))
.Build();
// ...
while (true)
{
// Consume a token from the token bucket. If a token is not available this method will block until
// the refill strategy adds one to the bucket.
bucket.Consume(1);
Poll();
}
Run Code Online (Sandbox Code Playgroud)
我还需要让它为我的项目异步,我只是做了一个扩展方法:
public static class TokenBucketExtensions
{
public static Task ConsumeAsync(this ITokenBucket tokenBucket)
{
return Task.Factory.StartNew(tokenBucket.Consume);
}
}
Run Code Online (Sandbox Code Playgroud)
使用它你不需要抛出/捕获异常,编写包装器变得相当简单
| 归档时间: |
|
| 查看次数: |
1731 次 |
| 最近记录: |