Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 执行任务onTextChanged会冻结用户界面_C#_Listbox_Datasource_Freeze - Fatal编程技术网

C# 执行任务onTextChanged会冻结用户界面

C# 执行任务onTextChanged会冻结用户界面,c#,listbox,datasource,freeze,C#,Listbox,Datasource,Freeze,我的应用程序中有一个文本框和一个列表框。我还有一个有很多玩家的文本文件。我想要的是,每当用户输入一些文本时,查看players文件并将匹配的players添加到匹配列表中,该列表是listbox的数据源。问题是,它看起来非常慢,UI冻结的时间很短,但这很烦人 这是我的代码: private void tb_playername_TextChanged(object sender, EventArgs e) { //This method is used to show user the

我的应用程序中有一个文本框和一个列表框。我还有一个有很多玩家的文本文件。我想要的是,每当用户输入一些文本时,查看players文件并将匹配的players添加到匹配列表中,该列表是listbox的数据源。问题是,它看起来非常慢,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;
    }
}
private void tb\u playername\u TextChanged(对象发送方,事件参数e)
{
//此方法用于向用户显示他可以使用输入的文本选择的选项
列表匹配_players=新列表();
foreach(所有玩家的var项目)
{
字符串播放器=item.f_name+“”+item.l_name;
if((player.IndexOf(tb_playername.Text,StringComparison.ordinallingorecase)>=0))
{
匹配玩家。添加(“+item.rating+”)+item.f\u name+“”+item.l\u name);
}
}
如果(tb_playername.Text.Length>=4)
{
匹配玩家。排序();
匹配玩家。反向()
listbox_matchingplayers.DataSource=匹配_玩家;
}
}

问题在于,您正在事件处理程序中执行一项相对耗时的任务。事件处理程序在同一个线程上运行,该线程负责呈现应用程序并处理应用程序的任何其他可视方面,因此,如果该线程很忙,它将无法立即对用户输入做出反应,因此会冻结

解决此问题的标准方法是将耗时的任务卸载到服务器上。后台工作线程将在新线程中操作,从而允许主线程继续处理UI事件。当涉及到使用后台工作程序时,这个示例应该有望使您走上正确的道路

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


后台工作程序将在完成时触发事件。您可以使用提取返回的列表,然后对其执行操作。

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

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;
}
解决此问题的标准方法是将耗时的任务卸载到服务器上。后台工作线程将在新线程中操作,从而允许主线程继续处理UI事件。当涉及到使用后台工作程序时,这个示例应该有望使您走上正确的道路

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

后台工作程序将在完成时触发事件。然后可以使用提取返回的列表并对其进行操作。

专用异步void tb\u playername\u TextChanged(对象发送方,事件参数e)
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;
}
{ var text=(发送者作为文本框); //检查文本的长度 if(string.IsNullOrEmpty(text)| | text.Length
private async void tb_playername_TextChanged(对象发送方,事件参数e)
{
var text=(发送者作为文本框);
//检查文本的长度

if(string.IsNullOrEmpty(text)| | text.Length如果用户在BW完成之前输入更多的文本呢?他不能像在后台线程中那样做,因为这些都是他正在使用的UI元素。我通常更喜欢使用异步,等待任务,因为我发现它们写起来更简单:,但当它不比原始问题复杂时,这个答案就足够了。@YuvalItzchakov在后台线程中添加项目后,只需从方法返回列表
matching\u players
,然后在UI线程上进行绑定即可。@Aldridge1991:请查看更新答案。我希望这会有所帮助。如果用户在BW完成之前输入更多文本怎么办?他不能像在后台线程中那样执行此操作,因为这些是他正在使用的UI元素。我通常更喜欢使用async,Wait tasks,因为我发现它们更容易编写:,但当它不比原始问题复杂时,这个答案就足够了。@YuvalItzchakov在后台线程中添加项目后,只需从方法返回列表
匹配的玩家
,然后执行bindi之后,在UI线程上出现ng。@Aldridge1991:请查看更新答案。我希望这有帮助。