领域在异步函数中搜索并在主线程中使用结果

时间:2017-12-04 11:13:52

标签: multithreading xamarin xamarin.android realm reactiveui

我需要根据关键字搜索我的一个Realm表。搜索功能在异步功能中完成,但速度很慢:3-5秒搜索并显示9000数据的结果。

搜索分三个步骤完成:

  • 根据查询进行搜索并返回Guid列表
  • 根据Guid列表
  • 返回对象列表
  • 使用结果值更新UI

当我尝试直接从xmlns:oxy="http://oxyplot.org/wpf" <oxy:Plot> <oxy:Plot.Series> <oxy:LineSeries ItemsSource="{Binding DataVM}" StrokeThickness="2" DataFieldX="X" DataFieldY="Y"/> </oxy:Plot.Series> <oxy:Plot.Axes> <oxy:LinearAxis Position="Bottom" Title="Title name"/> <oxy:LinearAxis Position="Left" Title="Title name, m"/> </oxy:Plot.Axes> </oxy:Plot> 返回List<IssueTable>时,我之后无法访问其属性,因为&#34;此领域实例已关闭&#34; (类似的东西)。

这是我的搜索功能:

SearchIssueInProject

包含功能:

public async Task<List<IssueTable>> GetFilteredIssuesInProject(string query)
{
     if (!string.IsNullOrEmpty(query))
     {
          var searchResults = await Task.Run(() => SearchIssueInProject(query));
          return searchResults.Select(i => RealmConnection.Find<IssueTable>(i)).ToList();
     }

     return this.AllIssuesInProject;
}

List<string> SearchIssueInProject(string query)
{
     using (var realm = Realm.GetInstance(RealmConfiguration))
     {
          Func<IssueTable, bool> searchIssue = d =>
                            string.IsNullOrEmpty(query) ? true :
                            Contains(d.Id.ToString(), query) ||
                            Contains(d.Status.DisplayName, query) ||
                            Contains(d.Status.Value, query) ||
                            Contains(d.Team.Name, query) ||
                            Contains(d.Team.Initial, query) ||
                            Contains(d.StandardIssueCategory.Title, query) ||
                            Contains(d.StandardIssueType.Title, query) ||
                            Contains(d.Drawing.Title, query) ||
                            Contains(d.Location.Title, query) ||
                            Contains(d.CreatedBy.DisplayName, query) ||
                            Contains(d.UpdatedBy.DisplayName, query);

          var result = realm.All<IssueTable>().Where(searchIssue)
                                  .OrderByDescending(i => i.UpdatedDate)
                                  .Select(i => i.Guid)
                                  .ToList();

          return result;
     }
}

        public List<IssueTable> GetAllIssues()
        {
            return RealmConnection.All<IssueTable>()
                            .OrderByDescending(i => i.UpdatedDate)
                            .ToList();
        }

这就是我使用搜索功能的方式:

public static bool Contains(string source, string filter)
{
     return source.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
}

如何改善搜索功能?

1 个答案:

答案 0 :(得分:0)

因为您正在创建一个函数而不是一个表达式,所以查询不是由Realm评估的,而是由LINQ到对象,这意味着每个对象都需要由Realm获取,然后访问的属性将被逐一取出以供比较使用。不幸的是,您搜索的所有字段都需要遍历Realm .NET尚不支持的相关对象。

解决此问题的一种方法是对数据进行非规范化并在IssueTable对象上复制这些属性。然后,您可以执行以下查询:

var result = realm.All<IssueTable>()
                  // Note that the .Where overload we select uses Expression<Func<>>
                  // Also, StatusDisplayName is a copy of Status.DisplayName
                  .Where(i => i.StatusDisplayName || ...)
                  .OrderByDescending(i => i.UpdatedDate)
                  .ToArray()
                  .Select(i => i.Guid)
                  .ToList();