以最大速率处理请求

时间:2015-09-21 08:46:35

标签: c# system.reactive reactive-programming

我正在使用Rx来确保我们的后端服从某些第三方API的请求限制。

下面的实现使用简单的for i=1:10 for j=1:10 if mod(i,2) ~= 0 & mod(j,2) ~= 0 fjnew = str2func(['@(x,l)','x','.^',num2str(j),'.*','(l-x)','.^',num2str(j)]) fj_diff = diff(fjnew,x) end end end 作为输入队列,然后使用James World's custom Pace operator tamed

只有在Subject<T>强制执行的主线程中没有观察到throttledRequests时,这是有效的。

一旦我注释掉这一行(第61行),该程序的行为就好像根本没有使用ObserveOn(TaskPoolScheduler.Default)运算符一样,并且请求再次以排队的速度再次处理。任何人都可以解释这种行为吗?

Pace

1 个答案:

答案 0 :(得分:2)

我无法完全回答问题(不确定为什么它会在ThreadPoolScheduler上运行)但我会告诉你我的想法并展示如何修复它以便在有或没有ThreadPoolScheduler的情况下按预期运行。

首先你可能会注意到,即使在ThreadPoolScheduler上它也无法正常工作 - 通常前1-3个项目会毫不拖延地得到处理。之后为什么他们开始延迟处理仍然不清楚。现在到了原因。请考虑以下示例代码:

var result = Observable.Range(0, 10).Delay(TimeSpan.FromSeconds(10)).StartWith(1).Take(1).ToTask().Result;

在这里,不会有任何延迟,任务将立即完成。为什么?因为StartWith立即在序列的开头注入“1”,然后Take(1)获取该值并完成 - 没有理由继续序列,因此永远不会执行延迟。如果你使用Take(2)代替它 - 它将在完成之前延迟10秒。

出于同样的原因,您的代码永远不会进入延迟(您可以通过在延迟后选择并记录到控制台来验证调试器)。要修复,只需删除Take(1)(或将其更改为Take(2)) - 无论如何,每个键始终只有一个项目。执行此操作时,无论是否使用ThreadPoolScheduler,代码都将正确运行。