Here's how you would do it with ReactiveUI:
IObservable<TheData> FetchNewData() { // TODO: Implement me } this.WhenAny(x => x.Property1, x => x.Property2, x => x.Property3, (x,y,z) => Unit.Default) .Throttle(TimeSpan.FromMilliseconds(200), RxApp.DeferredScheduler) .Select(x => FetchNewData()) .Switch() // We only care about the req corresp. to latest values of Prop1-3 .ToProperty(this, x => x.Data);
Update: Here's how to ensure that there is only one run at a time, with the caveat that you may not get the results in order.
this.WhenAny(x => x.Property1, x => x.Property2, x => x.Property3, (x,y,z) => Unit.Default) .Throttle(TimeSpan.FromMilliseconds(200), RxApp.DeferredScheduler) .Select(_ => Observable.Defer(() => FetchNewData())) .Merge(1) .ToProperty(this, x => x.Data);
The behavior that you describe would in fact be perhaps undesirable, because if the properties change, you get a queue of old requests that you want to publish - you can optimize this if you did something like "BufferingSwitch" () "an operator that did not return its results until it was sure that there were no changes - in fact, it would be great to write.
Moral of the story, Async Complicated ™ :)
Paul betts
source share