Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding multithreading C#

I am trying to understand multithreading. I have an example that runs two threads from Main method in console app.

new Thread(() =>
{
    for (int x = 0; x < 10; x++)
    {
        Console.WriteLine("First :" + x); 
    }
}).Start();

new Thread(() =>
{
    for (int x = 0; x < 10; x++)
    {
        Console.WriteLine("Second :" + x);
    }
}).Start();

Console.ReadKey();

What's happening is, My console is coming black, nothing written on it, but when I press any key then it displays proper results. Why?

like image 553
Imad Avatar asked Dec 19 '15 12:12

Imad


Video Answer


1 Answers

Some of us (looking at the comments under the question) see the new threads execute in entirety before Console.ReadKey() is called, while others see the initial thread preempt the new ones, waiting for input via Console.ReadKey() before executing the new threads.

You've got three threads all doing their own thing, all potentially writing to the console and performing other logic, and you're not really in control of which one executes at any particular moment.

From what Eric said, this behavior is expected, and the way you're executing the new threads is predictably unpredictable. (reposted his comment here in case the comments are cleaned up)

Read my two fundamental rules again: (1) programs that try to do UI on two threads are broken, and (2) don't expect anything to behave normally. I have no expectation that the broken program given will produce any behaviour whatsoever. Moreover, I don't expect that the behaviour of a broken program will be consistent across multiple runs or across machines. I also don't expect that the behaviour will be inconsistent. Broken programs are broken; they are not required to be consistent or inconsistent in their bad behaviour.

There is a call that will allow you to block the initial (main) thread (which happens to be the calling thread), until the new threads are finished executing, and that's Thread.Join. You're still not in control of which order the two new threads execute and write to the console, but at least the initial thread is paused.

var threads = new Thread[] {
    new Thread(() =>
    {
        for (int x = 0; x < 10000; x++)
        {
            Console.WriteLine("First :" + x);
        }
    }),
    new Thread(() =>
    {
        for (int x = 0; x < 10000; x++)
        {
            Console.WriteLine("Second :" + x);
        }
    })
};

// start the threads
foreach (var t in threads)
    t.Start();

// block the initial thread until the new threads are finished
foreach (var t in threads)
    t.Join();

// Now the following line won't execute until both threads are done
Console.ReadKey();
like image 79
Grant Winney Avatar answered Oct 28 '22 05:10

Grant Winney