Gustavo Mori
Gustavo Mori

Reputation: 8386

Threading in Visual Studio requires Join to work properly

This is more of an "I'd like to know" kind of question, than a real problem.

While working on improving my threading skills, and I'm running into the following conundrum.

The source code

internal class Program
{
    private static void Main(string[] args)
    {
        var thread = new Thread(() => Print("Hello from t"));
        thread.Start();
        //thread.Join();
    }

    private static void Print(string message)
    {
        Console.WriteLine(message);
    }
}

The problem

If I run the application from Visual Studio (regardless of whether it's Debug or Release configuration), the message is never displayed in the Output window unless I wait for the thread to exit (using Join).

The solution

Run the compiled executable from a command prompt, and you see the expected output.

My question

I'm gonna throw a wild guess and say that the Visual Studio environment makes all the difference.

What I'm wondering is, if I were working on a real-world application, how would I use Visual Studio to debug said application, without being forced to modify the source code (to use Join)?

Upvotes: 0

Views: 168

Answers (2)

Kendall Frey
Kendall Frey

Reputation: 44374

In a real-world application, this code should not appear because of the problem with the app quitting before the thread is completed. If you do have this problem, it usually signals a problem with the code.

If you are making use of a message pump (WinForms) or similar (WPF), the application will run as normal, meaning it won't exit until the user (or the application) breaks the loop by requesting the application exit. In this case, the thread will work until it finishes, or until the program exits. Thread.Join() may need to be called anyway, depending on the scenario.

If you are creating a console application, Thread.Join() should be called at the end of the program to ensure the worker thread completes. An alternative is to start the message pump with System.Windows.Forms.Application.Run(). However, it is not designed for this, and should not be used unless you are interacting with the user.

Another aspect, there are two kinds of threads in C#: foreground threads and background threads. Foreground threads keep running after the main thread has stopped. Background threads are stopped when all foreground threads are completed. The default type is a foreground thread. You can explicitly set a thread to background with the Thread.IsBackground property. Visual Studio apparently monkeys around with the threads to the point that the foreground thread doesn't prevent the application from quitting. Running the program outside of the debugger works fine.

It is still a good idea to be sure all threads terminate before the main thread. Who knows what might happen if you have more advanced code running after Main exits.

Upvotes: 2

Chris Dickson
Chris Dickson

Reputation: 12135

The call thread.Start() just starts the subsidiary thread and then returns. Since that's the end of your Main function, the program finishes and its process exits before the subsidiary thread has a chance to print the message.

No mystery, nothing weird about Visual Studio environment, just normal Windows process behaviour.

Upvotes: 2

Related Questions