【问题标题】:Dynamically search with interrupts,via Tasks C#通过任务 C# 使用中断动态搜索
【发布时间】:2015-11-10 13:29:01
【问题描述】:

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

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

1)需要将方法(我在数据库中查询)放在任务上(解锁我的主 UI 线程)

2)初始化定时器,然后开启:

  • 如果过了 1 秒,那么 => 在任务上运行我的方法(查询)(类似于后台线程)
  • 如果没有超过 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对不起我的英语。技能!

【问题讨论】:

    标签: c# multithreading task-parallel-library search-engine xamarin.forms


    【解决方案1】:

    一种方法是结合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);
            }
        }
    };
    

    【讨论】:

    • 谢谢!!正是我需要的,工作正常。 PS 但是当第一次引入时(一些值进入搜索栏),我得到一个异常(例如:在 android 设备上运行 - 调试显示“AndroidRunTimeThrowException”),但随后工作正常,奇怪的故障!
    • 没问题。我在 Android 应用程序上使用它并且没有得到任何异常。确保 CancellationTokenSource cancelTokenSource;处于班级的最高水平。
    • 是的,它的全局变量!奇怪...非常奇怪:)。明天病重复查。谢谢
    【解决方案2】:

    您希望在实际执行搜索之前等待。中途终止搜索任务可能会导致未定义的行为。

    您想保存当前的搜索过滤器并在 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 ();
    }
    

    【讨论】:

    • Thread.Sleep - 我认为这是针对 UI 线程的,不是吗?感谢您的建议!
    猜你喜欢
    • 1970-01-01
    • 2022-08-20
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多