Search code examples
c#.nettestingautomated-tests.net-6.0

ForEach method skips Console.WriteLine() on each iteration, then dumps all the logs when loop is done. Why?


I have this piece of code:

[Test]
public void LinqConsoleOutputTest() {
    Enumerable.Range(0, 10).ToList().ForEach(_ => {
        Thread.Sleep(500);
        Console.WriteLine($"Slept...");
    });
}

And to my surprise the code was executing around 5 seconds as expected, but it did not print to the console. It just dumped all 10 logs when it finished ForEach loop. And I am just curious why does it work that way? Is it related to ForEach/Linq or maybe to the Console object?


Solution

  • Console.WriteLine() writes to whatever is the Standard Output which might not be a console in case of a test. Run the same code in a simple "normal" C# program and it will print as expected.

    Consider this program:

    namespace MyProgram;
    
    class Program
    {
        static void Main(string[] args)
        {
            using var fileStream = File.OpenWrite("./consoleOutput.txt");
            using var streamWriter = new StreamWriter(fileStream);
            // redirect standard output
            Console.SetOut(streamWriter);
            Enumerable.Range(0, 10).ToList().ForEach(_ =>
            {
                Thread.Sleep(500);
                Console.WriteLine($"Slept... {DateTime.UtcNow}");
            });
            Console.WriteLine("Done");
        }
    }
    

    What this program does is, it redirects the standard output to write to a FileStream of a file called consoleOutput.txt. So when you run the program it creates the file and writes everything you would normally print to the console to the file. If you have a look at the file you can see that in fact it contains the whole output:

    consoleOutput.txt

    Slept... 6/3/2023 9:34:42 PM
    Slept... 6/3/2023 9:34:42 PM
    Slept... 6/3/2023 9:34:43 PM
    Slept... 6/3/2023 9:34:43 PM
    Slept... 6/3/2023 9:34:44 PM
    Slept... 6/3/2023 9:34:44 PM
    Slept... 6/3/2023 9:34:45 PM
    Slept... 6/3/2023 9:34:45 PM
    Slept... 6/3/2023 9:34:46 PM
    Slept... 6/3/2023 9:34:46 PM
    Done