Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Reactive Extensions to throttle SearchPane.SuggestionsRequested?

Reactive Extensions allow me to "observe" a stream of events. For example, when the user is typing their search query in the Windows 8 Search Pane, SuggestionsRequested is raised over and over (for each letter). How can I leverage Reactive Extensions to throttle the requests?

Something like this:

SearchPane.GetForCurrentView().SuggestionsRequested += (s, e) =>
{
    if (e.QueryText.Length < 3)
        return;
    // TODO: if identical to the last request, return;
    // TODO: if asked less than 500ms ago, return;
};

Solution

System.Reactive.Linq.Observable.FromEventPattern<Windows.ApplicationModel.Search.SearchPaneSuggestionsRequestedEventArgs>
    (Windows.ApplicationModel.Search.SearchPane.GetForCurrentView(), "SuggestionsRequested")
    .Throttle(TimeSpan.FromMilliseconds(500), System.Reactive.Concurrency.Scheduler.CurrentThread)
    .Where(x => x.EventArgs.QueryText.Length > 3)
    .DistinctUntilChanged(x => x.EventArgs.QueryText.Trim())
    .Subscribe(x => HandleSuggestions(x.EventArgs));

Install RX for WinRT: http://nuget.org/packages/Rx-WinRT/ Learn more: http://blogs.msdn.com/b/rxteam/archive/2012/08/15/reactive-extensions-v2-0-has-arrived.aspx

like image 544
Jerry Nixon Avatar asked Oct 04 '22 02:10

Jerry Nixon


1 Answers

There are Throttle and DistinctUntilChanged methods.

System.Reactive.Linq.Observable.FromEventPattern<Windows.ApplicationModel.Search.SearchPaneSuggestionsRequestedEventArgs>
    (Windows.ApplicationModel.Search.SearchPane.GetForCurrentView(), "SuggestionsRequested")
    .Throttle(TimeSpan.FromMilliseconds(500), System.Reactive.Concurrency.Scheduler.CurrentThread)
    .Where(x => x.EventArgs.QueryText.Length > 3)
    .DistinctUntilChanged(x => x.EventArgs.QueryText.Trim())
    .Subscribe(x => HandleSuggestions(x.EventArgs));

You might want/need to use different overload for DistinctUntilChanged, e.g. using different equality comparer or the Func<TSource, TKey> overload:

.DistinctUntilChanged(e => e.QueryText.Trim()) 

That will do what you want.

like image 129
Patryk Ćwiek Avatar answered Oct 13 '22 10:10

Patryk Ćwiek