2015-06-23 5 views
0

В настоящее время я реализую автозаполнение, которое запускает поиск в веб-службе, когда пользователь вводит текст.C# Наблюдаемая задержка до тех пор, пока не будет выполнено определенное условие

textChange.Subscribe(this.TextChanged); 

Кроме того у меня есть свойство в моем классе, указывающий, если поиск работает IsRunning.

Теперь я хочу буферизировать ввод пользователя, а IsRunning==true и запустить метод TextChange, только если IsRunning==false с введенным текстом.

Не могли бы вы мне помочь?

Edit: Пример кода, чтобы получить представление без использования реактивная:

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 
     } 
    } 
+0

Я обновил свой вопрос – coalmee

ответ

3

Поскольку вы не пробовали много с Rx себя я просто хочу, чтобы дать некоторые указатели:

  1. Lose isRunning bool, вы хотите попытаться сохранить как можно меньше состояний при использовании Rx.
  2. Используйте Select() для преобразования входной строки поиска в задачу, выполняющую поиск, чтобы задача вернула результаты.
  3. Используйте Switch() для удаления всех задач поиска, которые все еще выполняются, за исключением последней задачи поиска. См. Также: http://www.introtorx.com/content/v1.0.10621.0/12_CombiningSequences.html#Switch
  4. Вам необходимо преобразовать задачу поиска в наблюдаемую, используя Observable.FromAsync().
  5. При необходимости используйте Throttle(), чтобы ограничить количество запросов (поэтому ваш сервер не будет перегружен запросами).

Edit: так как вы не хотите использовать несколько запросов, выполняющихся в то же время, вы должны будете блокировать поток в то время как поиск работает. Вам нужно сделать что-то вроде:

searchTermStream  
.Select(l => Observable.FromAsync(asyncSearchMethod)) 
.Concat() 
.Subscribe(); 

Оператор Concat() убеждается задача запускается только после того, как предыдущий вернулся результат.

Я предсказываю, что это будет чувствовать себя лагги для пользователей, хотя, потому что поиск займет больше времени, чем пользователь должен ввести новый символ.

+0

Большое спасибо за эти подсказки. Я не хочу иметь несколько запросов одновременно. Поэтому, если один запрос выполняется, я просто хочу отложить ввод пользователя до первого завершения, а затем выполнить другой. – coalmee

+0

Это вернет * каждый * результат, хотя OP ищет промежуточные элементы для удаления. – paulpdaniels

+0

Я бы утвердил, что промежуточных элементов нет, когда вы выполняете весь алгоритм, блокирующий, как это, каждый элемент является последним элементом для каждого определения. – reijerh

Смежные вопросы