如何从Func中读取IObservable中的最新项目?

时间:2014-05-08 14:09:42

标签: c# .net system.reactive

我正在编写用户界面。在某些操作中,我想知道特定IObservable的最新值。我该怎么知道呢?

这是一个模拟我想要实现的目标的测试。你能帮忙解决一下吗?

var selectedItemOut = new Subject<int?>();

// idea: define some other IObservable or subject here

var getLatest = new Func<int?>(() =>
{
    // fix me
    return 0;
});

Assert.AreEqual(null, getLatest());

selectedItemOut.OnNext(4);
Assert.AreEqual(4, getLatest());

selectedItemOut.OnNext(5);
Assert.AreEqual(5, getLatest());

selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, getLatest());

3 个答案:

答案 0 :(得分:2)

如果你可以改变你的selectedItemOut主题是像Slugart这样的BehaviorSubject那将是最好的(我会将First()更改为Take(1),但那只是我)。如果你不能,那么你需要在函数范围之外创建一个变量。

var selectedItemOut = new Subject<int?>();

// Hold the last result from the OnNext
int? results = null;

// idea: define some other IObservable or subject here

// update var each time OnNext is called
var lastResult = selectedItemOut.Subscribe(i => results = i);

// just a wrapper around the results var.
var getLatest = new Func<int?>(() => results);
Assert.AreEqual(null, getLatest());

selectedItemOut.OnNext(4);
Assert.AreEqual(4, getLatest());

selectedItemOut.OnNext(5);
Assert.AreEqual(5, getLatest());

selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, getLatest());

//Need to tell the observable to stop updating the results var.
lastResultDispose.Dispose();

现在真的你的func只是引用结果var,你需要告诉它何时停止跟踪它。这不是很Rx,因为Rx是关于推送值而你想从中检索一个值。

答案 1 :(得分:2)

如果selectedItemOut可以是BehaviourSubject<int?>,则可以使用其Value属性:

var selectedItemOut = new BehaviorSubject<int?>(null);

var getLatest = new Func<int?>(() =>
{
    return selectedItemOut.Value;
});

否则CharlesNRice的回答看起来不错,或者您可以使用MostRecent

var mostRecent = selectedItemOut.MostRecent(null).GetEnumerator();    
var getLatest = new Func<int?>(() =>
{
    mostRecent.MoveNext();
    return mostRecent.Current;
});

// need to clean up this up
mostRecent.Dispose() 

答案 2 :(得分:0)

鉴于您需要初始值(即使它为空),然后是最新值,您可以将BehaviorSubjectFirst()一起使用。有关上下文的更多信息有助于提供更好的解决方案,因为不建议使用First()

var selectedItemOut = new BehaviorSubject<int?>(null);

// idea: define some other IObservable or subject here
Assert.AreEqual(null, selectedItemOut.First());

selectedItemOut.OnNext(4);
Assert.AreEqual(4, selectedItemOut.First());

selectedItemOut.OnNext(5);
Assert.AreEqual(5, selectedItemOut.First());

selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, selectedItemOut.First());