Alaa Salah
Alaa Salah

Reputation: 885

WPF application crashes when using System.Threading.Thread

I have a button named submit_Button which has the following code in the OnClicked event:

    Thread thread = new Thread(new ThreadStart(heavyWork));
    thread.Start();

heavyWork function code :

private void heavyWork()
{
    DisableUI();

    string Name = Name_textBox.Text;
    celebrityName = Name.Replace(" ", "+");
    string queryURL = "http://stackoverflow.com";

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(queryURL);
    request.Method = "GET";
    // make request for web page
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader htmlSource = new StreamReader(response.GetResponseStream());

    string htmlStringSource = string.Empty;
    htmlStringSource = htmlSource.ReadToEnd();
    response.Close();

    //var regex = new Regex(@"<FONT class=""result"">(.*?)</FONT>");
    var regex = new Regex(@"<span class=""kno-a-v"">(.*?)</span>");
    var match = regex.Match(htmlStringSource);
    var result = match.Groups[1].Value;

    result = HttpUtility.HtmlDecode(result);
    MessageBox.Show(result);

    EnableUI();
}

// Functions
private void DisableUI()
{
    celebrityName_textBox.IsEnabled = false;
    submit_Button.IsEnabled = false;
    infoType_listBox.IsEnabled = false;
    preloader_Image.Visibility = Visibility.Visible;
}

private void EnableUI()
{
    celebrityName_textBox.IsEnabled = true;
    submit_Button.IsEnabled = true;
    infoType_listBox.IsEnabled = true;
    preloader_Image.Visibility = Visibility.Hidden;
}

When I run the application, then press the button, the application crashes immediately!

What's happening ? I tried to use BackgroundWorker Instead, but when I can worker.RunWorkerAsync() nothing happens ( the worker doesn't start ).

Upvotes: 2

Views: 1032

Answers (3)

lordkain
lordkain

Reputation: 3109

When using Background Worker your code should look like something like this: Notice that when you start worker.RunWorkerAsync() method BackgroundWorkerDoWork is called

BackgroundWorker _backgroundWorker = new BackgroundWorker
{
   WorkerReportsProgress = true,
   WorkerSupportsCancellation = true
};
_backgroundWorker.DoWork += BackgroundWorkerDoWork;
_backgroundWorker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;

 void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
 {
     //DU STUFF HERE
 }

void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    /DO STUFF HERE LIKE HIDE / SHOW / ENABLE/ DISABLE buttons
}

Upvotes: 1

DavidN
DavidN

Reputation: 5197

DisableUI() is changing the state of UI controls on a thread which is not the UI thread. This is disallowed in WPF, because it is a single threaded UI framework, and only allows you to change controls on something called the UI thread. Dispatcher.Invoke()/BeginInvoke() is your friend.

Good MSDN article on using the Dispatcher

Upvotes: 3

JMK
JMK

Reputation: 28079

You are going to want to do any UI related stuff on the UI thread, you can do this with the dispatcher, like so:

private void heavyWork()
{
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(DisableUI));
    //rest of method
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnableUI));
}

Upvotes: 2

Related Questions