首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Rx.Net实现搜索

使用Rx.Net实现搜索
EN

Stack Overflow用户
提问于 2016-05-12 09:45:54
回答 1查看 121关注 0票数 0

我正在使用C#中的Rx创建一个搜索页面实现。我已经创建了一个通用搜索方法来搜索关键字并在UI上添加结果列表。以下是代码:

通用搜索方法:

代码语言:javascript
复制
   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;
            }

搜索泛型方法的用法:

代码语言:javascript
复制
  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;
            });

在这段代码中有两个问题需要帮助来修复:

  1. 在泛型方法行from result in search(propertyValue).TakeUntil(inputStringStream)中传递的搜索关键字值始终为null,因为propertyValue是字符串类型,因此作为值传递到方法中。如何在搜索方法中发送更新的值?
  2. 当在订阅方法上执行大量UI操作时,如添加大量随机数的示例所示。在重复执行搜索时,会引发此问题。最终UI块。我怎么才能解决这个问题?

对于第二点,有任何方法可以取消以前的UI操作并运行一个新的UI操作。这只是一个想法。但需要一些建议来解决这些问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-12 11:07:17

  1. 您可以传递一个读取属性值的函数,即您的方法应该接受TInput propertyValue,而不是Func<TInput> propertyValueGetter

您还可以使用ReactiveUI库。在这种情况下,代码如下所示:

代码语言:javascript
复制
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);
              })
  1. 我不相信这个问题有一个普遍的答案。只要在TaskPool上尽可能多地做,并且当您的数据准备好显示时,用ObserveOn切换到UI线程即可。在您的示例中,您可能可以按批插入项,而不是一次性插入所有项。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37183197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档