ReactiveExtensionsのThrottleの中でOnNextを呼んではいけない
はいやらかしました
まずはこちらのコードでどうなるか
static Subject<int> _subject; static void Main(string[] args) { _subject = new Subject<int>(); _subject.Subscribe(Func); _subject.OnNext(0); Console.ReadKey(); } static void Func(int i) { Console.WriteLine(i); if (i >= 10) return; _subject.OnNext(i + 1); }
コンソールに0から10まで出力されます。問題無しです
つぎにSubscribeの前にThrottleを入れて試してみます
// 他は同じなので割愛 _subject.Throttle(TimeSpan.FromSeconds(1)).Subscribe(Func);
コンソールには0しか出力されません
なぜか、はThrottleのソースを見ればすぐにわかります
上記リンクのOnNext
で_hasValue = true;
としてその次のPropagate
内のForwardOnNext
の後でfalse
にしています
ForwardOnNext
の先に私が書いたFunc
がいるわけで、その関数を抜けた後に_hasValue = false;
にしているのだからFunc
内でいくら次の値を発行しても無視されます
(説明下手は読み手の想像力でカバーしてください)
Throttle後は別スレッドになるのは知っていたので呼びっぱなしで次を処理しているものだと思い込んでいました。反省。
「処理の失敗時に少し待ってリトライ」みたいな時に↑みたいな感じで書いてしまうんですよねー