user3693167
user3693167

Reputation: 813

Handling threads in C# wpf application

I am making a C# wpf application with Visual Studio 2012. There are two textboxes named textboxInput and textboxOutput. My task is when I am typing in textboxInput it should bring the details in realtime into textboxOutput by searching a database. Since this takes some moment, it slows down my typing speed which the user never want.

The thing is when the user is typing "foo", it searches for "f", then "fo" and then "foo". There are database entries for all of that. The user only want to see the details of "foo" not others. But I cannot predict where will he stops typing. I want to give him a smooth typing without lagging. So my idea is using threads. In the testChanged event I search it with a Thread and if it again come to the textChange event(typed another letter) it kills the previous thread and runs a new Thread.

My current approach.

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

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

Could you please help me with that code inside

  1. My current code gives me the exception "The calling thread cannot access this object because a different thread owns it". How to handle it ?
  2. How can I implement the previous thread killing mechanism ? (I am a beginner :))
  3. Are there any other good ways to achieve my task ?

Upvotes: 2

Views: 195

Answers (2)

Rang
Rang

Reputation: 1372

you can do it like this:

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

never do it like this: it kills the previous thread and runs a new Thread.

Upvotes: 3

McGarnagle
McGarnagle

Reputation: 102723

The key point is that you can't access UI elements from background threads -- textBoxInput, for example. So you'll have to create a local copy of the Text property first:

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

Also, if the "search" function does some kind of UI manipulation, which I assume it does, then you'll need to send that operation back to the UI thread using Dispatcher.BeginInvoke():

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

Upvotes: 1

Related Questions