使用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中键入第一个字符时开始计数,并且对于您添加的每个字符,计时器都会重置。应用程序不会执行在数据库中搜索的部分,直到计时器达到设定的刻度数。
确保在表单中添加了timer
和backgroundWorker
。通过属性窗口创建事件,并添加以下代码:
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秒。