0

My question is that the object text initialized with "t1" and then a t1 thread started and then text becomes "t2" and later one more thread t2 started.

I was expecting:

t1
t2

Real output:

t2
t2

Why ?

class Program 
{
        static void Main()
        {
            string text = "t1";
            Thread t1 = new Thread(() => Console.WriteLine(text));
            t1.Start();
            text = "t2";
            Thread t2 = new Thread(() => Console.WriteLine(text));
            t2.Start();
        }
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Abdullah
  • 13
  • 3
  • 2
    t1.Start() starts the thread, but this happens asynchronous (30 ms delay), so it will happen in the background. By the time t1 is really started your code will already have finished.... and text wil be "t2". Put a Sleep(100) after t1.Start() and you will get the expected output. – Charles Dec 03 '21 at 10:25
  • 4
    Also see [what are 'closures' in .NET?](https://stackoverflow.com/questions/428617/what-are-closures-in-net) – Guru Stron Dec 03 '21 at 10:36
  • Rather than using sleeps, which you don't know if they will be enough and will basically mean you don't need the threads, you should look into something like [ParameterizedThreadStart](https://learn.microsoft.com/en-us/dotnet/api/system.threading.parameterizedthreadstart?view=net-6.0) – fredrik Dec 03 '21 at 10:43
  • Just bookmarked that question, very informative @GuruStron – Cleptus Dec 03 '21 at 11:13

2 Answers2

2

You don't need Threads (to get this result).

static void Main()
{
    string text = "t1";
    var action1 = () => Console.WriteLine(text);
    text = "t2";
    var action2 = () => Console.WriteLine(text);
 
    action1();  // "t2"
    action2();  // "t2"
}

The culprit here is the lambda operator, not the Threads. The variable text is 'closed over' or 'captured', both actions will use the same variable and the value at the time of execution, not the value of when they were created.

When you run the actions on separate Threads you have a race condition, run your program many times and you might see a "t1" sometimes.

H H
  • 263,252
  • 30
  • 330
  • 514
0

Constructing a Thread (allocating a thread ) consumes time. Therefore while your thread is going up and running, the background thread will do its work, and apparently, it's done before t1 print out text object. Defining local variables inside of the thread's scope is safer than defining them on global scopes. Shared data must be used with caution.

R.Abbasi
  • 89
  • 10