0

我正在C#中使用Rx創建搜索頁面實現。我創建了一個通用搜索方法來搜索關鍵字並在UI上添加結果列表。下面是代碼:使用Rx.Net搜索實現

通用搜索方法:

public static IObservable<TResult> GetSearchObservable<TInput, TResult>(INotifyPropertyChanged propertyChanged, 
       string propertyName, TInput propertyValue, Func<TInput, TResult> searchFunc) 
      { 
       // Text change event stream 
       var searchTextChanged = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                ev => propertyChanged.PropertyChanged += ev, 
                ev => propertyChanged.PropertyChanged -= ev 
               ) 
                .Where(ev => ev.EventArgs.PropertyName == propertyName); 

       // Transform the event stream into a stream of strings (the input values) 
       var inputStringStream = searchTextChanged.Throttle(TimeSpan.FromMilliseconds(500)) 
                 .Select(arg => propertyValue); 

       // Setup an Observer for the search operation 
       var search = Observable.ToAsync<TInput, TResult>(searchFunc); 

       // Chain the input event stream and the search stream, cancelling searches when input is received 
       var results = from searchTerm in inputStringStream 
           from result in search(propertyValue).TakeUntil(inputStringStream) 
           select result; 

       return results; 
      } 

的搜索一般使用方法:

var rand = new Random(); 
      SearchObservable.GetSearchObservable<string, string>(this, "SearchString", SearchString, search => 
      { 
       Task.WaitAll(Task.Delay(500)); 

       return SearchString; 
      }) 
      .ObserveOnDispatcher() 
      .Subscribe(rese => 
      { 
       LstItems.Clear(); 

       LstItems.Add(SearchString); 

       // Heavy operation lots of item to add to UI 
       for(int i = 0; i < 200000; i++) 
       { 
        LstItems.Add(rand.Next(100, 100000).ToString()); 
       } 

       Result = rese; 
      }); 

有這碼2個問題需要幫助解決這些:

  1. 在通用方法行from result in search(propertyValue).TakeUntil(inputStringStream)中傳遞的搜索關鍵字始終爲null,因爲propertyValue是字符串類型,因此將其作爲值傳遞給方法。如何在搜索方法中發送更新的值?

  2. 當重UI操作已經對訂閱方法如在加入一些大量的隨機數的示例來完成。重複執行搜索時會導致此問題。最終UI塊。我怎樣才能解決這個問題?

對於第二點是否有任何方法來取消以前的UI操作並運行一個新的。這只是一個想法。但需要一些建議來解決這些問題。

回答

0
  1. 您可以通過一個函數讀取屬性值,即代替TInput propertyValue你的方法應該接受Func<TInput> propertyValueGetter

您還可以使用ReactiveUI庫。在這種情況下,您的代碼會是這個樣子:

this.WhenAnyValue(vm => vm.SearchString) 
    .Throttle(TimeSpan.FromMilliseconds(500)) 
    .InvokeCommand(DoSearchString); 

DoSearchString = ReactiveCommand.CreateAsyncTask(_ => { 
    return searchService.Search(SearchString); 
}); 

DoSearchString.ObserveOn(RxApp.MainThreadScheduler) 
       .Subscribe(result => { 
        LstItems.Add(result); 
       }) 
  • 我不相信有這個問題,一般的答案。只需儘可能多地在TaskPool上執行操作,並且當數據準備好顯示時,切換到UI線程ObserveOn。在你的情況下,你可以通過批次插入項目,而不是一次全部插入。