繁体   English   中英

在C#WPF应用程序中处理线程

[英]Handling threads in C# wpf application

我正在用Visual Studio 2012开发C#wpf应用程序。有两个名为textboxInput和textboxOutput的文本框。 我的任务是,当我在textboxInput中键入内容时,应该通过搜索数据库将详细信息实时地带入textboxOutput中。 由于这花了一些时间,因此减慢了用户从未希望的打字速度。

问题是当用户键入“ foo”时,它先搜索“ f”,然后搜索“ fo”,然后搜索“ foo”。 所有这些都有数据库条目。 用户只希望查看“ foo”的详细信息,而不希望查看其他内容。 但是我无法预测他将在哪里停止打字。 我想给他一个流畅的打字而又不拖延。 所以我的想法是使用线程。 在testChanged事件中,我用一个线程进行搜索,如果再次遇到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. 还有其他好的方法可以完成我的任务吗?

您可以这样做:

   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

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

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

另外,如果“搜索”功能执行某种类型的UI操作(我认为是这样),那么您将需要使用Dispatcher.BeginInvoke()将操作发送回UI线程:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM