Use Reactive Extensions to do high-cost operation in TextChanged event

The TextChanged event is often used to trigger some operations when the content of a textbox changes. While this is fine for simple and fast, if we need to perform a time consuming operation like a database query or IO operating in a frequently triggered event like TextChanged and ValueChanged, it is quite likely that the frontend will become unresponsive or laggy.

However, for most situations, we don’t actually need to handle this until the user finishes typing. With TextChanged, a series of events would be rapidly triggered, and each event in turn triggers some costly operation that will unnecessarily lag our app, leading to a less than desirable user experience.

We can remedy this issue using a class library design for parallel programming called Reactive Extensions(Rx). The library is developed by Microsoft, and it allows us to handle the TextChanged event only when the user finishes typing while discarding all TextChanged events before that.

We can download the library and add it to our project using NuGet. Next, in our backend, add

1
using System.Reactive.Linq;

For our purpose, we want to set up a delayed event handler. We initialize the handler when the page is first loaded (i.e. add the following line of code to MainPage_Loaded or wherever you want the delayed event handler to be set up).

1
Observable.FromEventPattern<AutoSuggestBoxTextChangedEventArgs>(this.QueryBox, "TextChanged").Throttle(TimeSpan.FromMilliseconds(500)).Subscribe(async x =>; DoSomeThing());

Of course, if we are listening for a different event or a different control type, we will need to replace AutoSuggestBoxTextChangedEventArgs with the right type of event args and change this.QueryBox into the right event sender.

The method Throttle(this IObservable<TSource> source, TimeSpan dueTime) ignores elements from an observable sequence which are followed by another element within a specified relative time duration. In our code, we set it up to ignore all but the last events triggered in each 500ms interval. Subscribe<T>(this IObservable<T&> source, Action<T> onNext) allows us to subscribe to the event and install an event handler.

p.s. WPF offers a Delay property in data binding which can also finish the work above. Unfortunately, this Delay property hasn’t been supported in UWP yet