0

I have a static method in a class:

public static void MakeThreadModified(string s)
{
    new Thread(() => 
    {
        Thread.CurrentThread.IsBackground = true; 
        /* run your code here */
        while (true)
        {
            Console.WriteLine(s);
            Thread.Sleep(500);
        }

    }).Start();
}

And I call this method in Main() like this:

    string[] str = {"A", "B", "C", "D", "E"};
    foreach (var v in str)
    {
        MakeThreadModified(v);
    }

I was suprised to find that the result is:

A
E
C
B
D

But why do I have this result? I thought that it would print the letters from 'A' to 'E' on the console continuously without stop, but it just prints every letter one time each. So why is this happening?

SWIIWII
  • 387
  • 5
  • 15

4 Answers4

8

Since you've set the threads .IsBackground property to true, this threads do not keep you application alive. so after your MakeThreadModified-loop ends the program ends and so the threads... Add a Console.ReadLine() after your loop to keep the application alive...

Michael
  • 1,931
  • 2
  • 8
  • 22
1

Another option might be to join to all of the threads to prevent them from terminating.

But it is probably easier to use Tasks.

See: Create multiple threads and wait all of them to complete

Derek
  • 7,615
  • 5
  • 33
  • 58
0

Try using the code below instead. I suspect you do not have a Console.ReadLine() at the end of main.

class Program
{
    static void Main( string[ ] args )
    {
        string[ ] str = { "A", "B", "C", "D", "E" };
        foreach( var v in str )
        {
            MakeThreadModified( v );
        }
        Console.ReadLine( );
    }

    public static void MakeThreadModified( string s )
    {
        new Thread( obj =>
        {
            Thread.CurrentThread.IsBackground = true;
            /* run your code here */
            while( true )
            {
                Console.WriteLine( $"[{Thread.CurrentThread.ManagedThreadId}] {( string )obj}" );
                Thread.Sleep( 500 );
            }

        } ).Start( s );
    }
}
WBuck
  • 5,162
  • 2
  • 25
  • 36
0

Well, I'm not a C# developer, but it's a common concept among programming field that the main() of certain program runs in one specific thread (the main thread) and in the same way other threads just exits when their work is done and aren't in a infinite loop situation, the main thread finishes as well, regardless any other thread running parallel to it. Because of that when the main thread ends you won't receive any output from any other thread since the program main output is tied to the main thread (the one you started when called the program).

The correct thing to do is as @Derek stated before: "join all of the threads" before main thread termination. The join() acts like a semaphore to the main thread when called, i.e.: for each .join() called to on a specific thread, the main function must wait for that specific thread to finish.

t1.Join();
t2.Join();
t3.Join();

forces main thread to wait t1, t2 and t3. The problem here is that you create anonymous threads, so there isn't a simple way to refer to them.

As I said earlier: I'm not a C# developer, so I don't really know what would be the best way possible to handle it (maybe through a pool of threads?), but the aforementioned solution of adding Console.ReadLine() might solve the problem, even being not related to the other threads at all, it's just a 'trick' to make main thread wait something (an input from the user).

The idea of my entire post is to warn you about the existence of a main thread that doesn't care or know about other threads running in parallel if you doesn't explicitly notifies it (through .join()).