使用textBox_TextChanged事件和if语句一起写入文本框变得越来越慢

本文关键字:文本 越来越 一起 TextChanged textBox 事件 语句 if 使用 | 更新日期: 2023-09-27 18:11:13

我正在使用c#和Windows窗体制作一个字典。在我的字典中,我有一个textBox,用户可以在其中搜索单词以获得其含义。我在comboBox中也有一些选项,用户可以选择一种语言来查看该语言的含义。因为我正在为不同的语言编写字典。

我的代码如下:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    string word = textBox1.Text;
    SqlCeConnection con = new SqlCeConnection(@"Data Source=" + Directory.GetCurrentDirectory() + @"'Database'condrokothadb.sdf;Password=000;");
    //in combobox there are 2 option(language)
    //if select one language(option) from combobox
    if(mood=="bangla") 
    {
        SqlCeDataAdapter b = new SqlCeDataAdapter("SELECT english,bangla FROM dic WHERE (bangla like '" + word + "%')", con);
        DataTable tt = new DataTable();
        b.Fill(tt);
        dataGridView1.DataSource = tt;
    }
    else   //by default english language is selected 
    {
        using (con)
        {
            con.Open();              
            using (SqlCeDataAdapter b = new SqlCeDataAdapter("SELECT english,bangla FROM dic WHERE (english like '" + word + "%')", con))
            {
                DataTable tt = new DataTable();
                b.Fill(tt);
                dataGridView1.DataSource = tt;
            }
        }
    }
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (((ComboBox)sender).SelectedItem.ToString() == "Bangla")
    {
        mood = "bangla";
    }
    else if (((ComboBox)sender).SelectedItem.ToString() == "English")
    {
        mood = "english";
    }
}

我的问题是,当一个用户想要写一些东西到文本框,它是越来越慢写。我怎样才能克服呢?

使用textBox_TextChanged事件和if语句一起写入文本框变得越来越慢

这是一个有趣的问题,我将如何解决它。

我添加了一个计时器,当您在textBox中键入第一个字符时开始计数,并且对于您添加的每个字符,计时器都会重置。应用程序不会执行在数据库中搜索的部分,直到计时器达到设定的刻度数。

确保在表单中添加了timerbackgroundWorker。通过属性窗口创建事件,并添加以下代码:

int timerTicks;
int waitUntill = 10; //10 = 1 second. Change this to decide how long the application will wait.
string mood;
string word;
string langConnection;
DataTable tt;
SqlCeConnection con;
SqlCeDataAdapter b;
private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (!timer1.Enabled)
        timer1.Start();
    //Reset the timer when a character is entered in textBox1.
    timerTicks = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
    timerTicks++;
    if (timerTicks > waitUntill && !backgroundWorker1.IsBusy && comboBox1.SelectedItem != null)
    {
        //Stop the timer and begin the search in a background thread.
        timer1.Stop();
        word = textBox1.Text;
        mood = comboBox1.SelectedItem.ToString();
        backgroundWorker1.RunWorkerAsync();
    }
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    tt = new DataTable();
    con = new SqlCeConnection(@"Data Source=" + Directory.GetCurrentDirectory() + @"'Database'condrokothadb.sdf;Password=000;");
    langConnection = String.Format("SELECT english,bangla FROM dic WHERE ({0} like '{1}%')", mood, word);
    using (con)
    {
        con.Open();
        b = new SqlCeDataAdapter(langConnection, con);
        b.Fill(tt);
    }
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    dataGridView1.DataSource = tt;
}

请注意,您不需要comboBox1_SelectedIndexChanged事件来工作。

编辑:

要使实际的搜索运行得更快,您必须在启动时打开连接,并在整个执行过程中保持连接打开,就像其他答案所建议的那样。不过,你应该能够自己弄清楚。

而不是从服务器在每一个文本更改数据,你可以得到所有的数据在网格一次,然后用dataview过滤它们。

// to get data in grid
CustomList<wordlistDAO> WordList = null;
WordList = WordListBLL.GetAllWord();
GridWord.DataSource = WordList ;
// create word datatable for filtering 
DataTable dtWord = null;
dtWord = new DataTable();
foreach (DataGridViewColumn colu in GridWord.Columns)
                        dtWord .Columns.Add(new DataColumn(colu.HeaderText));
foreach (DataGridViewRow row in GridWord.Rows)
{
   DataRow dr = dtWord.NewRow();
   foreach (DataGridViewCell cell in row.Cells)
        dr[row.Cells.IndexOf(cell)] = cell.Value;
        dtWord .Rows.Add(dr);
}
//create data view
DataView wordlistview = new DataView();
wordlistview  = new DataView(dtWord);
// filter dataview and show in grid
if (cboLanguage.Text == "Bangla")
 {
   wordlistview.RowFilter = "bangla LIKE '" + txtSearchValue.Text.Trim().ToUpper() + "%'";
 }
else
{
 wordlistview.RowFilter = "english LIKE '" + txtSearchValue.Text.Trim().ToUpper() +    "%'";
}   
 GridWord.DataSource = wordlistview;

主要问题是,每次在文本框中按下一个键时,都是在创建一个数据库连接并查询数据库。这是非常低效的!此外,由于您的孟加拉代码没有处理连接,您可能会保留许多不需要的引用对象,因此您可能会发现性能随着时间的推移而下降。

一个基本的建议是使用一个连接,而不是为每次按键打开新的连接。这将在一定程度上减少查询所花费的时间。但实际上,我怀疑您希望立即加载数据的全部内容,并在内存中运行查询。这会让你的速度更快。

在后台线程上运行查询将有助于保持UI的响应性,但可能会导致大量查询同时运行,试图赶上用户的输入。

一个更好的解决方案是考虑运行一个"idle-timer",只在用户停止输入很短时间后才启动查询。我建议仍然使用后台线程。您不需要为每次按键都查询数据库,也不会影响UI的响应性。

延迟可能是由于数据库中有大量数据,并且您要为每个文本更改事件调用数据库。我的建议是把所有的数据都放到DataView中,然后用view的结果过滤和绑定网格。这样你就可以最小化数据库被调用的次数。

在任何击键时在数据库中进行搜索是一种不好的做法。正如您已经体验过的那样,它使UI非常缓慢。更好的选择是在后台线程中进行搜索,而不是在每次击键时进行搜索。在进行搜索之前,您可以等待一段时间(例如0.5秒)。如果用户在此期间按了其他键,则再次将等待时间延长0.5秒。