Reputation: 1556
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
}
}
Upvotes: 0
Views: 1042
Reputation: 815
Since you haven't tried much with Rx yourself I'm just going to give some pointers:
isRunning
bool, 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:
searchTermStream
.Select(l => Observable.FromAsync(asyncSearchMethod))
.Concat()
.Subscribe();
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.
Upvotes: 3