【问题标题】:Problems performing an asynchronous search (WPF/C#)执行异步搜索的问题 (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。

标签: c# wpf async-await uwp task


【解决方案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 并保持应用响应。
猜你喜欢
  • 2016-07-25
  • 2020-05-14
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 2014-05-13
  • 1970-01-01
  • 2010-10-28
相关资源
最近更新 更多