繁体   English   中英

通过任务C#动态搜索中断

[英]Dynamically search with interrupts,via Tasks C#

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

所以问题来自于性能,因为我的数据库有百万条记录和简单的LINQ查询工作非常慢。换句话说,当用户输入的数据太快时,应用程序会有很大的滞后,有时会崩溃
为了解决这个问题,我想到了一些事情(理论上的解决方案):

1)需要在任务上放置方法(我对db进行查询)(解锁我的主UI线程)

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

  • 如果1秒过去 ,那么=>在任务上运行我的方法(查询)(类似于后台线程)
  • 如果1秒没有通过 ,则退出匿名方法。

类似的东西(类似)或任何建议。谢谢!

UPD:
所以说实话,我尝试了太多,并没有得到一个好结果
BTW ,我目前的代码(Snippets):
1)我的SearchMethod

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秒传递,然后我将进行查询以更新我的listItems列表(每次,当用户输入一些值到搜索栏,这个触发器(计时器) )必须再次刷新为零)。

任何帮助将不胜感激,谢谢!
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);
        }
    }
};

您想在实际执行搜索之前等待 在中途杀死搜索任务可能会导致未定义的行为。

您想要保存当前搜索过滤器,并在1秒后再次对其进行比较。 如果没有改变,请进行搜索。 否则,中止:

searchBar.TextChanged += async (sender, e) => 
{
    var filter = searchBar.Text;
    await Task.Run(() =>
    {
        Thread.Sleep(1000);
        if (filter == searchBar.Text)
            listview.QueryToDB(searchBar.Text);
    });
};

以保持视图模型更新,将您isBusy分配内部QueryToDB ,因为这是当你的视图模型是真正的忙:

public void QueryToDB(string filter)
{
    this.BeginRefresh ();
    ViewModel.isBusy = true;

    // do your search

    ViewModel.isBusy = false;
    this.EndRefresh ();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM