执行异步搜索的问题 (WPF/C#)

Posted

技术标签:

【中文标题】执行异步搜索的问题 (WPF/C#)【英文标题】:Problems performing an asynchronous search (WPF/C#) 【发布时间】:2022-01-11 02:52:48 【问题描述】:

我目前正在为 UWP 包做一个搜索系统,想法是通过在 TextBox 中键入将显示与 ListBox 中的文本匹配的结果。

我的想法是创建一个任务,在文本更改时过滤与搜索匹配的包。

private async void OnSearchBox_TextChanged(object sender, TextChangedEventArgs e)

     if (searchBox.Text != "")
     
        tokenSource = new();
        token = tokenSource.Token;
        await Dispatcher.InvokeAsync(() =>
        
                appsListBox.ItemsSource = (from Package package in packageManager.FindPackagesForUser("")
                                          where
                                             package.DisplayName.ToLower().Contains(searchBox.Text.ToLower())
                                          select package);
                if (token.IsCancellationRequested)
                    System.Diagnostics.Debug.WriteLine("Task canceled");
        , DispatcherPriority.Background, token);
    

从那时起,当文本不断变化时,取消之前的任务,以防它尚未完成,为创建新任务让路。

private void OnSearchBox_PreviewTextInput(object sender, TextCompositionEventArgs e)

    if (tokenSource != null)
        tokenSource.Cancel();

简而言之,“PreviewTextInput”将取消正在运行的任务,以防万一。然后“TextChanged”将使用当前文本创建一个新的搜索任务,依此类推,直到您停止输入文本片刻,以便“TextChanged”可以完成其最终任务并显示其结果。

我目前收到图片中显示的错误,我想知道是否有人可以帮助我,或者给我一些关于如何修复该错误的指导,或者提供一些更优化的方法来执行我上面描述的操作.

【问题讨论】:

Dispatcher.InvokeAsync 可能没有按照您的想法进行。它只是调度回调 Action 以便稍后在 UI 线程上执行。您可能想看看 Task.Run。 【参考方案1】:

为什么要使用异步?下面的代码怎么样?

using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace SearchDataGrid

    public partial class MainWindow : Window
    
        ObservableCollection<Person> list = new ObservableCollection<Person>();
        public MainWindow()
        
            InitializeComponent();

            list.Add(new Person  ID = 1, Name = "Tom", Age = "11" );
            list.Add(new Person  ID = 2, Name = "Smith", Age = "22" );
            list.Add(new Person  ID = 3, Name = "Jimin", Age = "33" );
            list.Add(new Person  ID = 4, Name = "John", Age = "44" );

            dataGrid.ItemsSource = list;
        

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        
            TextBox tb = sender as TextBox;
            dataGrid.ItemsSource = list.Where(x => x.Name.Contains(tb.Text));
        
    


【讨论】:

强烈建议使用异步,以免冻结 GUI 并保持应用响应。

以上是关于执行异步搜索的问题 (WPF/C#)的主要内容,如果未能解决你的问题,请参考以下文章

我们如何使用WPF / C#可执行文件调试DLL(使用本机C / C ++的bulit)源?

如何在 C++ 中异步执行 curl_multi_perform()?

使用异步操作运行同步代码

使用异步操作运行同步代码

如何让一个方法在继续执行之前等待另一个(异步)方法完成?

在 WPF / C# 中选择绑定项目后维护组合框文本