I'm currently implementing an autocomplete which triggers a search on a web service when a user enters a text.
textChange.Subscribe(this.TextChanged);
Additionally I have a property in my class indicating if a search is running IsRunning.
Now I want to buffer the user input while IsRunning==true and fire the TextChange method only if IsRunning==false with newly entered text.
Could you help me out?
Edit: Sample code to get the idea without using reactive:
public class AutoComplete
{
private bool isRunning;
private string textBuffer;
public AutoComplete()
{
this.textChanged += this.TextChanged;
}
public void TextChanged(string text)
{
if (isRunning) textBuffer = text;
else Search(text);
}
public void Search(string text)
{
isRunning = true;
// DoSearch()
isRunning = false;
// TODO: Search finished, check if textBuffer was filled and reexecute search with the new termn
}
}
Since you haven't tried much with Rx yourself I'm just going to give some pointers:
isRunningbool, you want to try to keep as little state as possible when using Rx.Select()to transform the input search string to a Task that performs the search, have the Task return the results.Switch()to discard all search tasks that are still in progress except for the last search task. See also: http://www.introtorx.com/content/v1.0.10621.0/12_CombiningSequences.html#SwitchObservable.FromAsync().Throttle()to limit the number of requests (so your server won't be overloaded with requests).Edit: since you don't want multiple searches running at the same time, you'll need to block the stream while a search is running. You'll need to do something like:
The
Concat()operator makes sure a task is only started after the previous one has returned a result.I predict this is going to feel laggy for the users though, because the searches will take longer than the user needs to enter a new character.