执行onTextChanged任务会冻结UI

时间:2015-01-14 08:55:08

标签: c# listbox datasource freeze

我的应用中有一个文本框和一个列表框。我还有一个包含许多玩家的文本文件。我想要的是每当用户输入一些文本时,查看播放器文件并将匹配的播放器添加到匹配列表中,该列表是列表框的数据源。问题是它似乎很慢并且UI冻结了很短的时间,但它非常烦人。

这是我的代码:

private void tb_playername_TextChanged(object sender, EventArgs e)
{

    //This method is used to show user the options he can choose with the text he has entered
    List<string> matching_players = new List<string>();

    foreach (var item in all_players)
    {
        string player = item.f_name + " " + item.l_name;

        if ((player.IndexOf(tb_playername.Text, StringComparison.OrdinalIgnoreCase) >= 0))
        {
            matching_players.Add("(" + item.rating + ") " + item.f_name + " " + item.l_name);
        }
    }

    if (tb_playername.Text.Length >= 4)
    {
        matching_players.Sort();
        matching_players.Reverse()                
        listbox_matchingplayers.DataSource = matching_players;
    }
}

2 个答案:

答案 0 :(得分:3)

问题是您在事件处理程序中执行相对耗时的任务。事件处理程序在同一个线程上运行,负责渲染应用程序并处理它的任何其他视觉方面,因此如果此线程忙,它将无法立即对用户输入作出反应,因此冻结。

解决此问题的标准方法是将耗时的任务卸载到Background Worker。后台工作程序将在新线程中操作,从而允许主线程继续处理UI事件。在使用后台工作者时,This示例应该会让您走上正确的道路。

编辑:根据您的问题,您可以做的只是在输入特定数量的字符时开始搜索,例如3,这将减少后台工作程序运行的时间。如果用户继续键入,您可以在运行时停止当前的后台工作程序并启动新的后台工作程序。

后台工作程序将在完成后触发事件。您可以使用RunWorkerCompletedEventArgs.Result然后提取返回的列表行为。

答案 1 :(得分:1)

private async void tb_playername_TextChanged(object sender, EventArgs e)
{
  var text = (sender as TextBox).Text;

  // Check length of the text
  if (string.IsNullOrEmpty(text) || text.Length <= 3)
    return;

  // Check timer to not process if user still typing, by measuring the key stoke time
  ...

  // Filtering
  List<string> matching_players = await PlayerFilter(text);

  // Minimize listbox layout time
  listbox_matchingplayers.SuspendLayout();
  listbox_matchingplayers.DataSource = matching_players;
  listbox_matchingplayers.ResumeLayout();
}

//Time consuming method
private async Task<List<string>> PlayerFilter(string text)
{
  //This method is used to show user the options he can choose with the text he has entered

  return matching_players;
}

有关用户输入检查wait for user to finish typing in a Text Box

的详细信息