0

你好大师我在表单中有一个 DataGridView 对象。在服务类中,我有一个方法

Form.CheckForIllegalCrossThreadCalls = false;
Thread tr1 =
    new Thread(() =>
    {
        List<Musteri> list = null;
        IEnumerable<Musteri> result = from Musteri m in Db4OService.Database
                                      where (
                                                m.servisAdi.Contains(text) ||
                                                m.il.Contains(text))
                                      select m;
       list = result.ToList<Musteri>();


        DataGridView dataGridView = ((DataGridView)sayfa.Controls.Find("dataGridView1", false)[0]);
        DataTable dt = ListToDataTable(list);
        try
        {
            dataGridView.DataSource = dt;
            dataGridView.Refresh();
        }
        catch (Exception e)
        {
                Console.Write(e);

        } 

    });
tr1.Start();

此方法每次都从 textBox 的 textChanged 方法调用。所以我想让打字时流畅。当我在一个线程中做所有事情时,我必须等待搜索方法完成才能输入另一个字母。我的方法不起作用:(欢迎任何帮助。谢谢!!

4

3 回答 3

0

不想在这里学习您的英语,但尚不清楚您帖子中的代码是在 TextChangedEvent 上调用还是代码生成 TextChangeEvent。此外,该代码是否适用于生涩的打字?我希望代码有问题。

  1. 我将假设在您的 TextChangedEvent 上调用提供的代码,该代码从数据库中查找数据并填充网格。
  2. 我看到您正在尝试从非 GUI 线程更新您的网格。首先,从非 GUI 线程更新 GUI 是个坏主意。
  3. 根据我对您想要做的事情的理解,最好让这个线程成为一个可跟踪的变量,所以当用户输入一些文本时,如果您的搜索仍然没有返回,您可能想要停止您的数据库查找,因为用户可能输入了更多内容。底线是用户键入可能会更改您的搜索条件和显示结果,因此您应该能够取消搜索和网格更新,否则您只是在浪费资源搜索用户不再感兴趣的内容。

下面是我将如何编码:

bool searching = false;
object searchThreadLock = new object();
Thread searchThread = null;

void TextChangedEvent() {
    lock (searchThreadLock) {
        if (searching && searchThread != null && searchThread.IsAlive)
            searchThread.Abort();

        lookupForData();
    }
}

void lookupForData() {
    searchThread = new Thread( () => {
        // Your code to retrieve relevant data from DB based on your TextChangedEvent goes here
        searching = true;
        try {
            List<Musteri> list = null;
            IEnumerable<Musteri> result = 
                from Musteri m in Db4OService.Database
                    where (
                        m.servisAdi.Contains(text) ||
                        m.il.Contains(text))
                    select m;
            list = result.ToList<Musteri>();
            DataTable dt = ListToDataTable(list);
            updateGrid(dt);
        } catch (ThreadAbortException ex) {
        } finally {
            searching = false;
        }
    } );
    searchThread.start();
}

void updateGrid(DataTable dt) {
    DataGridView dataGridView = ((DataGridView)sayfa.Controls.Find("dataGridView1", false)[0]);
    if (dataGridView.InvokeRequired) {
        dataGridView.BeginInvoke(new Action<DataTable>(updatdeGrid), dt);
        return;
    }

    // Your code to update the grid goes here
    dataGridView.DataSource = dt;
    dataGridView.Refresh();
}

PS:请注意 Thread.Abort 通常是一个坏主意,它应该由您的应用程序特定逻辑代替以停止数据库搜索。我已将其落实到位,因为我不确定如何正确停止您的 LINQ 查询。

于 2012-07-28T23:43:25.990 回答
0
Form.CheckForIllegalCrossThreadCalls = false;

这很糟糕,学会不要使用它。永远永远永远永远。阅读有关调用的信息。

于 2013-10-08T08:41:06.810 回答
0

您将不得不使用BackgroundWorker 类将工作分开并由另一个线程完成, 这将免费帮助文本框在后台完成工作时保持解冻状态

于 2012-07-28T21:59:17.310 回答