あなたのメソッドをpublic IObservable<int> Add(IObservable<Tuple<int, int>> values)
のようなものに書き換えることができない限り、Rxを使うのは意味がないと思います。
レートリミットの懸念を別のクラスに分けることです。そうすれば、あなたのコードは次のようになります:
public class RateLimitingCalculator
{
private RateLimiter rateLimiter = new RateLimiter(5, TimeSpan.FromSeconds(1));
public async Task<int> Add(int a, int b)
{
rateLimiter.ThrowIfRateExceeded();
//...
}
}
RateLimiter
の実装では、あなたの正確な要件に依存しますが、非常に単純ではなく、スレッドセーフバージョンは、次のようになります。
class RateLimiter
{
private readonly int rate;
private readonly TimeSpan perTime;
private DateTime secondStart = DateTime.MinValue;
private int count = 0;
public RateLimiter(int rate, TimeSpan perTime)
{
this.rate = rate;
this.perTime = perTime;
}
public void ThrowIfRateExceeded()
{
var now = DateTime.UtcNow;
if (now - secondStart > perTime)
{
secondStart = now;
count = 1;
return;
}
if (count >= rate)
throw new RateLimitExceededException();
count++;
}
}
[this post](http://stackoverflow.com/a/36933908/3407841)にはいくつかのアイデアがあります。 – leetibbett
あなたは本当にモナドの混合を避けるべきです。私はあなたがこの署名を持っていれば、これを推論する方が簡単だと思う: 'public IObservable Add(IObservable 値)'。 –
Enigmativity
@Enigmativity "モナドの混合を避ける"とはどういう意味ですか?また、Rxを使用してAPIのレートを制限することが理にかなっていると思いますか? – SuperJMN