我正在使用Db(通过 SQLite.NET PCL ,不是异步版本)。目前,我有一个 ListView ,其中包含一些数据(取自db),也有一个搜索栏/条目(其nvm),用户可以在其中输入一些值,然后通过 LINQ 我将进行查询并更新列表的 SourceItems

因此,性能带来了问题,因为我的 DB 获得了上百万条记录,而简单的 LINQ 查询工作却非常缓慢。换句话说,当用户输入某些数据太快时,应用程序会出现巨大的滞后,并且有时会使崩溃。
为了解决这个问题,我想到了一些事情(理论上是解决方案):

1)需要在Task上放置方法(我将查询到db)(解锁我的主UI线程)

2)初始化计时器,然后打开并:

  • 如果1秒钟传递了,则=>在Task(类似于后台线程)上运行我的方法(查询)
  • 如果1秒未通过,则退出匿名方法。

  • 诸如此类(类似)或任何建议。谢谢!

    UPD:
    所以说实话,我尝试了太多,却没有取得好的结果
    顺便说一句,我当前的代码(摘录):
    1)我的搜索方法
    public void QueryToDB(string filter)
            {
                this.BeginRefresh ();
    
                if (string.IsNullOrWhiteSpace (filter))
                {
                    this.ItemsSource = SourceData.Select(x => x.name); // Source data is my default List of items
                }
                else
                {
                    var t = App.DB_Instance.FilterWords<Words>(filter); //FilterWords it's a method,where i make direct requests to the database
                    this.ItemsSource = t.Select(x => x.name);
                }
                this.EndRefresh ();
            }
    

    2)Searchbar.TextChanged(匿名方法)
    searchBar.TextChanged +=async (sender, e) =>
                    {
                        ViewModel.isBusy = true;  //also i got a indicator,to show progress,while query working
                        await Task.Run(()=> //my background,works fine
                        {
                            listview.QueryToDB(searchBar.Text);
                        });
                        ViewModel.isBusy = false; // after method is finished,indicator turn off
    
                    };
    

    主要问题是如何实现此部分(在这种情况下),其中经过了1秒钟,然后才进行查询以更新列表的 sourceItems (每次,当用户在搜索栏中输入一些值时,都会触发此触发器) (计时器)必须再次刷新为零)。

    任何帮助将不胜感激,谢谢!
    PS对不起,我的英语。技能!

    最佳答案

    一种方法是结合async Task.RunCancellationTokenSource:

    CancellationTokenSource cancellationTokenSource;
    
    searchView.TextChanged += async (sender, e) =>
    {
        if (cancellationTokenSource != null) cancellationTokenSource.Cancel();
        cancellationTokenSource = new CancellationTokenSource();
        var cancellationToken = cancellationTokenSource.Token;
    
        var searchBar = (sender as SearchBar);
        if (searchBar != null)
        {
            string searchText = searchBar.Text;
            try
            {
                await Task.Delay(650, cancellationToken);
    
                if (cancellationToken.IsCancellationRequested) return;
    
                var searchResults = await Task.Run(() =>
                {
                    return ViewModel.Search(searchText);
                });
    
                if (cancellationToken.IsCancellationRequested) return;
    
                ViewModel.YouItems.Repopulate(searchResults);
            }
            catch (OperationCanceledException)
            {
                // Expected
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
    };
    

    关于c# - 通过Tasks C#动态搜索中断,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32058379/

    10-14 12:04