1

我正在使用 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";
    }
}

我的问题是,当用户想在文本框中写一些东西时,写起来会慢得多。我该如何克服呢?

4

5 回答 5

2

This is an interesting question and here is how I would solve it.

I added a timer that starts to count as you type the first character into your textBox, and for every character you add the timer resets. The application wont execute the part where you search through the database untill the timer reaches a set number of ticks.

Make sure you add a timer and a backgroundWorker into the form. Create the events through the properties window and add this code:

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;
}

Note that you don't need the comboBox1_SelectedIndexChanged event for this to work.

EDIT:

To make the actual search run faster you would have to open the connection at startup and keep it open throughout the entirety of the execution, like other answers suggest as well. You should be able to figure that out for yourself though.

于 2013-04-29T11:20:38.907 回答
1

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

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

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

更好的解决方案是考虑运行“空闲计时器”,并且仅在用户停止输入很短的时间时才开始查询。我建议仍然为此使用后台线程。您不会为每个按键查询数据库,也不会影响 UI 的响应能力。

于 2013-04-29T09:43:42.053 回答
1

延迟可能是由于数据库中有大量数据,并且您正在为每个文本更改事件调用数据库。我的建议是将所有数据放入 DataView 并继续过滤和绑定网格与视图中的结果。这样,您可以最大限度地减少调用数据库的次数。

于 2013-04-29T09:49:57.300 回答
1

您可以一次获取网格中的所有数据,然后使用 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;
于 2013-04-30T05:41:38.427 回答
1

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

于 2013-04-29T09:46:14.783 回答