我在这里使用以下代码 - 在清除“重播缓存”时对我来说是一个问题
https://gist.github.com/leeoades/4115023
如果我更改以下调用和代码,我发现重播中存在错误,即它永远不会被清除。有人可以帮忙纠正这个问题吗?
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);
}
答案 0 :(得分:2)
问题是一个微妙的问题。源序列Timer
在发出事件后完成,该事件又调用由OnCompleted
创建的内部ReplaySubject
上的Replay
。当Subject
完成后,即使显示新的Observable
,它也不再接受任何新值。
当您重新订阅它再次执行的基础Observable
时,但无法重新启动Subject
,因此您的新Observer
只能在ReplaySubject
之前收到最新值{1}}已完成。
最简单的解决方案可能就是永远不要让源流完成(未经测试):
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);
}
答案 1 :(得分:0)
此处针对类似问题的解决方案(How can i clear the buffer on a ReplaySubject?)是否为您提供了所需的功能?