I have a scenario where I have a Windows Store Application, there is a page with a search functionality, the user types names in a textbox and the app searches for names similar to the typed text.
Searching is done through calling a RESTful GET Api method. the call takes about 4 seconds to retrieve the results. This uses the c# async/await technique.
What I want to do is to do is to call the HTTP method as the user types, but I want to do this by cancelling any executing tasks and making sure that only one task executes at a time to avoid flooding the server with requests.
I implemented the following approach, it works fine, but I believe there can be better solution:
- I hold a reference to the async task and a cancellation token source.
As the user types, I check if there is a running task, I cancel it and start a new one with the most recent search text.
private CancellationTokenSource cts = null; private Task<List<string>> searchTask; private async void textbox_TextChanged(object sender, TextChangedEventArgs e) { //there is already running task if (searchTask != null && !searchTask.IsCompleted) { //cancel the running and start a new one cts.Cancel(); cts = new CancellationTokenSource(); searchTask=SearchWeb(txtbox.Text, cts.Token); searchTask.ContinueWith(t =>{ //show results }); } else { //start a new one searchTask = dataRepository.SearchUsers(txtbox.Text, cts.Token); searchTask.ContinueWith(t =>{ //show results }); } }
My primary concern is that I don't like the overhead generated with tracking the running tasks. It seems like there should be a more efficient way of doing this that doesn't require cancelling so many requests.