Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What am I doing wrong with Threading?

Synopsis:

I am trying to convert a non threaded application to a threaded application. I have not used threads in an application in about 10 years and am very rusty with the concept. There is just something I am not grasping. Can you please look at my (very short) before and after code to see what I am doing wrong and why it is wrong? All help is greatly appreciated! Thanks!

Errors seen:

My code is not responding. I can run and execute the buttons to launch the applications but rather than start a new thread and just work, they freeze and show a "not responding" message. I am not sure what i did wrong. Did i just implement the threads incorrectly?

Non threaded code:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
    //userform UserForm = new userform();
    //UserForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

Broken threaded code:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(enumerationStuff);
    bg.RunWorkerAsync();

}
//run enumeration application in new thread
private void enumerationStuff(object sender, DoWorkEventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(correlationStuff);
    bg.RunWorkerAsync();
}
//run correlation application in new thread
private void correlationStuff(object sender, DoWorkEventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}
like image 862
toosweetnitemare Avatar asked Feb 19 '23 16:02

toosweetnitemare


2 Answers

BackgroundWorkers are designed for doing just that - working in the background. They aren't designed to display new windows or present any UI themselves - that by definition is foreground work. BackgroundWorkers don't handle any messages, so they won't respond to mouseclicks, keyboard input, or anything at all, which is why the windows just display "Not Responding".

It's difficult to answer this question since I'm not really clear on what you're actually trying to achieve here. What's wrong with your first, non-threaded code?

If the "individual applications" (which are really just forms) are freezing the entire application, they're probably doing an awful lot of work in the UI thread. In that case, BackgroundWorkers could be a solution, but you're using them in the wrong place. Find the code that's doing "lots of work" (whatever work that is), and see if you can put that code (and only that code) into a BackgroundWorker. What you can't do, though, is do anything with the UI from inside a BackgroundWorker - you only have one UI thread (the one you start in), and only that thread can touch the UI.

like image 99
Chris Avatar answered Feb 28 '23 01:02

Chris


The .NET/Windows user interface does not allow performing any UI operation from anything from the single user interface thread. In a nutshell, the UI itself is single threaded, while any long running operations that don't touch the UI can happily occur in a secondary/background thread.

This is why things like Control.Invoke exist, to allow you to request a particular piece of code be executed in the UI thread context.

like image 42
Pete Avatar answered Feb 28 '23 00:02

Pete