Why Does This Simple .Net Console App Have So Many Threads

Why does this simple .NET console app have so many threads?

Try running it outside the debugger (i.e. press Ctrl+F5 instead of F5). You should only see three threads - the main thread, the GC thread & the finalizer thread IIRC. The other threads you see are debugger-related threads.

Why 3 threads for a basic single threaded c# console app?

If you're running a .NET application, I believe you always get a thread (mostly sleeping) for the JIT (Just-in-Time compiler) as well as the GC (Garbage Collection) thread, in addition to your main thread.

Default threads in c# very small console application ( Visual Studio 2012 )

In brief, these extra threads are GC, Finalizer, VS, and Debugger related. The link below provides a more detailed answer to your question:

Why does this simple .NET console app have so many threads?

How can I keep a Console App open when all processes are running on separate threads in c#?

You need to join your threads before exiting.

static public void Main()
{
/*
Existing code goes here
*/

//Before exiting, make sure all child threads are finished
foreach (var thread in connectionThreads) thread.Join();
}

When your program calls Thread.Join, it is telling the operating system that it needn't schedule the main thread for any timeslices until the child thread is finished. This makes it lighter weight than other techniques, such as busywaiting (i.e. running a while loop); while the main thread will still hold onto resources, it won't consume any CPU time.

See also When would I use Thread.Join? and c# Waiting for multiple threads to finish

C# .Net 4.0 Console App - how to stay alive until all threads complete?

Are the threads spawned for a loop? If so a Parallel.ForEach would work:

ParallelOptions options = new ParallelOptions();
Parallel.ForEach(items, options, item=>
{
// Do Work here
});

What happens when a .NET console app blocks on Console.ReadLine()?

There's no definite number.

Your code is only running on one thread - the main thread. Calling Console.ReadLine doesn't create a new thread, it just starts an I/O request and waits for it to be processed - this requires no threads, but since you're using the synchronous API, there's no way to release your thread, so it just blocks. If the interviewer wanted just one number, this is the number - it's the only application thread you have, everything else is an implementation detail.

There's a lot of infrastructure threads - the Garbage Collector threads are the main ones, and some of those are created and destroyed all the time.

Finally, there's the threads somewhere in between - most notably, the thread pool. Since you're not using the thread-pool, it will have the default number of threads - unless the configuration says otherwise, this is usually two threads per logical CPU core.

The reality goes even deeper. For example, .NET threads are managed threads, and they may skip between "native" threads at the will of the runtime. However, this is something you never really need to care about unless you're writing your own .NET runtime or an operating system :) Or, doing heavy interop with native code that depends on native thread-affinity (again, not very common).

I suspect the main purpose of the question is to get you talking about how the Windows threading model works, how .NET handles threads and what kinds of threads there are in a typical windows/.NET application. But mainly, to get you to talk :P

Thread control flow in async .NET Console program

In short, When the SynchronizationContext.Current not is set, (which is the case on a console application). The await response is invoked on the ThreadPool.

On a Winforms/WPF a SynchronizationContext is implemented to queue the response to either the winforms controlToSendTo.BeginInvoke(); or the WPF Dispatcher.BeginInvoke();.

Reference:

  • Await, SynchronizationContext, and Console Apps (a blog post by a member of the dev team):

    But there's one common kind of application that doesn't have a SynchronizationContext: console apps. When your console application's Main method is invoked, SynchronizationContext.Current will return null. That means that if you invoke an asynchronous method in your console app, unless you do something special, your asynchronous methods will not have thread affinity: the continuations within those asynchronous methods could end up running "anywhere."

  • Parallel Computing - It's All About the SynchronizationContext (an article referenced from the official documentation for the SynchronizationContext class):

    By default, all threads in console applications and Windows Services only have the default SynchronizationContext.

    ...

    Figure 4 Summary of SynchronizationContext Implementations

    ...

    ╔═════════╦═══════════╦════════════╦════════════╦══════════╦══════════╗
    ║ ║ Specific ║ Exclusive ║ Ordered ║ Send May ║ Post May ║
    ║ ║ Thread ║ (Delegates ║ (Delegates ║ Invoke ║ Invoke ║
    ║ ║ Used to ║ Execute ║ Execute ║ Delegate ║ Delegate ║
    ║ ║ Execute ║ One at ║ in Queue ║ Directly ║ Directly ║
    ║ ║ Delegates ║ a Time) ║ Order) ║ ║ ║
    ╠═════════╬═══════════╬════════════╬════════════╬══════════╬══════════╣
    ║ ... ║ ║ ║ ║ ║ ║
    ╠═════════╬═══════════╬════════════╬════════════╬══════════╬══════════╣
    ║ Default ║ No ║ No ║ No ║ Always ║ Never ║
    ╚═════════╩═══════════╩════════════╩════════════╩══════════╩══════════╝


Related Topics



Leave a reply



Submit