public PagedDataViewer(ITradeService tradeService, ISchedulerProvider schedulerProvider) { //build observable predicate from search text var filter = this.WhenValueChanged(t => t.SearchText) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(BuildFilter); //build observable sort comparer var sort = SortParameters.WhenValueChanged(t => t.SelectedItem) .Select(prop => prop.Comparer) .ObserveOn(schedulerProvider.Background); //build observable comparer var currentPageChanged = PageParameters.WhenValueChanged(p => p.CurrentPage); var pageSizeChanged = PageParameters.WhenValueChanged(p => p.PageSize); var pager = currentPageChanged.CombineLatest(pageSizeChanged, (page, size) => new PageRequest(page, size)) .StartWith(new PageRequest(1, 25)) .DistinctUntilChanged() .Sample(TimeSpan.FromMilliseconds(100)); // filter, sort, page and bind to observable collection _cleanUp = tradeService.All.Connect() .Filter(filter) // apply user filter .Transform(trade => new TradeProxy(trade), new ParallelisationOptions(ParallelType.Ordered, 5)) .Sort(sort, SortOptimisations.ComparesImmutableValuesOnly) .Page(pager) .ObserveOn(schedulerProvider.MainThread) .Do(changes => PageParameters.Update(changes.Response)) .Bind(out _data) // update observable collection bindings .DisposeMany() // dispose when no longer required .Subscribe(); }