我的目标是从观察中获得两个订阅者,但我只对事件流中的最新项目感兴趣。我希望别人被抛弃。将此视为股票价格屏幕,每1秒更新一次并忽略任何中间值。 这是我的代码:
var ob = Observable.Interval(TimeSpan.FromMilliseconds(100)) // fast event source
.Latest().ToObservable().ToEvent();
ob.OnNext += (l =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000); // slow processing of events
Console.WriteLine("Latest: " + l);
});
ob.OnNext += (l =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000); // slow processing of events
Console.WriteLine("Latest1: " + l);
// subject.OnNext(l);
});
然而,作为上述代码的结果,尽管我附加了两个事件(即使您使用订阅符号也无关紧要)仅定期调用第一个订阅。第二个根本不运行。为什么会这样?
答案 0 :(得分:2)
首先,我认为您的要求是以下之一:
1)的代码
var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
.Publish();
ob.Connect();
2)的代码
var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
.Replay(1);
ob.Connect();
3)的代码
var ob = Observable.Interval(TimeSpan.FromMilliseconds(1000)) // fast event source
.Replay(1);
ob.Connect();
var latest = ob.Take(1);
4)的代码可以是这样,但是你认为窗口有一些微妙的行为。
var ob = Observable.Interval(TimeSpan.FromMilliseconds(200)) // fast event source
.Replay(1);
//Connect the hot observable
ob.Connect();
var bufferedSource = ob.Buffer(TimeSpan.FromSeconds(1))
.Where(buffer => buffer.Any())
.Select(buffer => buffer.Last());
5)的代码可以在James World的博客http://www.zerobugbuild.com/?p=192上找到,并且在伦敦的许多银行应用程序中很常见。
答案 1 :(得分:1)
我认为您不了解.Latest()
的作用。
public static IEnumerable<TSource> Latest<TSource>(
this IObservable<TSource> source
)
可枚举序列,在每次迭代时返回最后一个采样元素,然后阻塞,直到可观察源序列中的下一个元素变为可用。
请注意,它阻止等待来自observable的下一个元素。
因此,当您使用IObservable<>
将IEnumerable<>
变为.Latest()
时,您必须使用.ToObservable()
将其重新设置为IObservable<>
才能使用.ToEvent()
致电var ob = Observable.Interval(TimeSpan.FromMilliseconds(100)).ToEvent();
。这就是它倒下的地方。
此代码的问题在于您正在创建阻止的代码。
如果你这样做,那就有效:
.Latest()
无需调用.ToEvent()
,因为您始终从可观察的内容中获取最新值。你永远无法获得更早的价值。这是一个可观察的,而不是时间机器。
我也不明白为什么你在任何情况下都在呼叫var ob = Observable.Interval(TimeSpan.FromMilliseconds(100));
ob.Subscribe(l =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000); // slow processing of events
Console.WriteLine("Latest: " + l);
});
ob.Subscribe(l =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000); // slow processing of events
Console.WriteLine("Latest1: " + l);
});
。有什么需要?
这样做:
PictureBox