【问题标题】:Handling threads in C# wpf application在 C# wpf 应用程序中处理线程
【发布时间】:2014-07-25 00:23:59
【问题描述】:

我正在使用 Visual Studio 2012 制作 C# wpf 应用程序。有两个名为 textboxInput 和 textboxOutput 的文本框。我的任务是当我输入 textboxInput 时,它应该通过搜索数据库将详细信息实时带入 textboxOutput。由于这需要一些时间,它会减慢我的打字速度,这是用户所不希望的。

问题是当用户输入“foo”时,它会搜索“f”,然后是“fo”,然后是“foo”。所有这些都有数据库条目。用户只想查看“foo”的详细信息,而不是其他人。但我无法预测他会在哪里停止打字。我想给他流畅的打字而不会滞后。所以我的想法是使用线程。在 testChanged 事件中,我使用 Thread 搜索它,如果它再次出现 textChange 事件(键入另一个字母),它会终止前一个线程并运行一个新线程。

我目前的做法。

private void textBoxInput_TextChanged(object sender, TextChangedEventArgs e){
    //textBoxOutput.Text=search(textBoxInput.Text);  //previos approach

    //Current approach
    new Thread(delegate() {search(textBoxInput.Text); }).Start();
}

你能帮我看看里面的代码吗

  1. 我当前的代码给了我异常“调用线程无法访问这个对象,因为不同的线程拥有它”。如何处理?
  2. 如何实现之前的线程杀死机制? (我是初学者:))
  3. 还有其他好方法可以完成我的任务吗?

【问题讨论】:

    标签: c# wpf multithreading delegates thread-safety


    【解决方案1】:

    你可以这样做:

       Thread thread;
                bool flag = false;
                public MainWindow()
                {
                    InitializeComponent();
                    thread = new Thread(new ThreadStart(search));
                    thread.Start();
                }
    
                private void textBoxInput_TextChanged(object sender, TextChangedEventArgs e)
                {
                    if(flag)
                       return;
                    flag = true;
                }
    
                private void search()
                {
                    while(true)
                    {
                        if(flag)
                        {
                            string result = search(textBoxInput.Text);
                            this.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                textBoxOutput.Text = result;
                            }));
                            flag = false;
                        }
                        Thread.Sleep(200);
                    }
                }
    

    永远不要这样做: it kills the previous thread and runs a new Thread

    【讨论】:

    • 谢谢。这提供了令人敬畏的流畅打字。几个问题。我减少了Thread.Sleep(50) 中的时间以使其更流畅。但与复杂性相比,它占用了大量的处理器。删除睡眠调用几乎使用了 i5 处理器的一半。有什么建议可以让低处理器用户保持流畅度?
    • @user3693167 抱歉,我帮不了你。建议你提出一个新问题以获得更多帮助。
    • 从 wpf 退出时是否必须明确终止这些线程?注意到当我从 bin/debug/application.exe 运行应用程序时,在我退出应用程序后它仍保留在任务管理器和进程中?
    • @user3693167 是的,你可以在窗口关闭事件中实现。 thread.abort()
    • 应该明确吗? wpf 不处理吗?
    【解决方案2】:

    关键是您不能从后台线程访问 UI 元素——例如 textBoxInput。因此,您必须首先创建 Text 属性的本地副本:

    string text = textBoxInput.Text;
    new Thread(delegate() { search(text); }).Start();
    

    此外,如果“搜索”函数执行某种 UI 操作,我假设它确实如此,那么您需要使用 Dispatcher.BeginInvoke() 将该操作发送回 UI 线程:

    Dispatcher.BeginInvoke(new Action(() => {
        // UI operation here
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多