[英]Rx Cache - Replay operator Clear
I am using the following code from here - looks like an issue to me in clearing the " Replay cache " 我在这里使用以下代码-清除“ 重放缓存 ”对我来说似乎是一个问题
https://gist.github.com/leeoades/4115023 https://gist.github.com/leeoades/4115023
If I change the following call and code like this I see that there is bug in Replay ie it is never cleared. 如果我更改下面的调用和类似的代码,我会发现Replay中存在错误,即从未清除。 Can someone please help to rectify this ?
有人可以帮助纠正这一点吗?
private Cache<string> GetCalculator()
{
var calculation = Observable.Create<string>(o =>
{
_calculationStartedCount++;
return Observable.Timer(_calculationDuration, _testScheduler)
.Select(_ => "Hello World!" + _calculationStartedCount) // suffixed the string with count to test the behaviour of Replay clearing
.Subscribe(o);
});
return new Cache<string>(calculation);
}
[Test]
public void After_Calling_GetResult_Calling_ClearResult_and_GetResult_should_perform_calculation_again()
{
// ARRANGE
var calculator = GetCalculator();
calculator.GetValue().Subscribe();
_testScheduler.Start();
// ACT
calculator.Clear();
string result = null;
calculator.GetValue().Subscribe(r => result = r);
_testScheduler.Start();
// ASSERT
Assert.That(_calculationStartedCount, Is.EqualTo(2));
Assert.That(result, Is.EqualTo("Hello World!2")); // always returns Hello World!1 and not Hello World!2
Assert.IsNotNull(result);
}
The problem is a subtle one. 问题是一个微妙的问题。 The source sequence
Timer
completes after it emits an event, which in turn calls OnCompleted
on the internal ReplaySubject
created by Replay
. 源序列
Timer
在发出事件后完成,该事件又对Replay
创建的内部ReplaySubject
调用OnCompleted
。 When a Subject
completes it no longer accepts any new values even if a new Observable
shows up. Subject
完成后,即使出现新的Observable
它也不再接受任何新值。
When you resubscribe to the underlying Observable
it executes again, but isn't able to restart the Subject
, so your new Observer
can only receive the most recent value before the ReplaySubject
completed. 重新订阅基础
Observable
它将再次执行,但无法重新启动Subject
,因此新的Observer
只能在ReplaySubject
完成之前接收最新值。
The simplest solution would probably just be to never let the source stream complete (untested): 最简单的解决方案可能就是永远不要让源流完成(未经测试):
public Cache(IObservable<T> source)
{
//Not sure why you are wrapping this in an Observable.create
_source = source.Concat(Observable.Never())
.Replay(1, Scheduler.Immediate);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.