0

I have a simple console app which does Console.WriteLine. The problem is that when I execute the program, it is not writing some of the texts to the console. (Timer #1 : 10 seconds is missing i.e.)

And it happens if I increase the i on:

for (int i = 0; i < 100000; i++)
{
    Console.WriteLine(mainThread.Name);
}

If I set i to 1000 or something smaller it writes all to the console. Here is my code.

using FightClub.MultiThreading;

Thread mainThread = Thread.CurrentThread;
mainThread.Name = "Main Thread";

Thread thread1 = new Thread(() => CountUp());
Thread thread2 = new Thread(() => CountDown());

thread1.Start();
thread2.Start();

for (int i = 0; i < 100000; i++)
{
     Console.WriteLine(mainThread.Name);
}

static void CountDown()
{
    for (int i = 10; i >= 0; i--)
    {
        Console.WriteLine("Timer #1 : " + i + " seconds");
        Thread.Sleep(1000);
    }
    Console.WriteLine("Timer #1 is complete!");
}

static void CountUp()
{
    for (int i = 0; i <= 10; i++)
    {
        Console.WriteLine("Timer #2 : " + i + " seconds");
        Thread.Sleep(1000);
    }
    Console.WriteLine("Timer #2 is complete!");
}

I have tried setting the thread priorities to high but nothing changed.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
farid-mmzd
  • 19
  • 1
  • Looks like a classic race condition to me. The main thread is exiting before the worker threads are done – edtheprogrammerguy Apr 06 '23 at 18:41
  • 2
    You need to wait for both threads to complete before the app exits. Console apps will shutdown and therefore kill all threads that belong to them. – Charleh Apr 06 '23 at 18:46
  • 1
    ​So your program writes 100,022 lines in the console, and you are missing one line? How do you check this, by scrolling the window of the console and looking at each individual line? Sounds quite tedious to me! – Theodor Zoulias Apr 06 '23 at 18:54
  • what is the point of printing like this on the poor console ? do your calculations and collect your data using a thread safe collection like `ConcurrentBag` and then write it on the console or a file. https://www.c-sharpcorner.com/article/concurrency-and-the-concurrentbag-in-c-sharp/ – RezaNoei Apr 06 '23 at 18:56
  • @RezaNoei no, [not the](https://stackoverflow.com/questions/15521584/what-is-the-correct-usage-of-concurrentbag/75343790#75343790) `ConcurrentBag`! – Theodor Zoulias Apr 06 '23 at 19:03
  • 1
    @Charleh The threads aren't background threads, so no, that won't happen. – Servy Apr 06 '23 at 19:11
  • 2
    In your title you refer to the compiler, yet the question appears to be about runtime execution. Can you clarify? What does the compiler have to do with this? – Rufus L Apr 06 '23 at 19:27
  • @TheodorZoulias copying all output into notepad and then searching for text – farid-mmzd Apr 06 '23 at 20:17
  • Does the console has enough space for 100,022 lines? I mean, have you verified that a single-thread program can write 100,022 lines in the console, that you can then copy to the Notepad and find all the text that the program is expected to write? – Theodor Zoulias Apr 06 '23 at 21:52

1 Answers1

-2

While you certainly can manually wrangle threads, unless you have a clear reason to, why not just simplify your code and use Tasks instead (and here is previous Task vs Thread discussion if you are interested) What is the difference between task and thread? Now your code reads a little cleaner (probably up to personal preference), fix your race condition, and you get rid of the Thread.Sleep that will cause other headaches: Why is Thread.Sleep so harmful

 List<Task> taskList = new()
 {
    CountDown(),
    CountUp(),
 };

await Task.WhenAll(taskList);

static async Task CountDown()
{
    for (int i = 10; i >= 0; i--)
    {
        Console.WriteLine("Timer #1 : " + i + " seconds");
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
    Console.WriteLine("Timer #1 is complete!");
}
static async Task CountUp()
{
    for (int i = 0; i <= 10; i++)
    {
        Console.WriteLine("Timer #2 : " + i + " seconds");
        await Task.Delay(TimeSpan.FromSeconds(1));
    }
    Console.WriteLine("Timer #2 is complete!");
}
Anthony G.
  • 452
  • 2
  • 7