简体   繁体   中英

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?

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();

Let me call the first spawned thread as thread1, the next spawned thread as thread2. Moreover let's call the thread which creates thread1 and thread2 as mainthread.

Loosely speaking, there is no guarantee that code in thread1 will get executed before that of thread2 or mainthread. So depending on various circumstances, it might execute some Console.WriteLine() before stopping for Console.ReadKey() .
Why does it stop for Console.ReadKey() you may ask; since the Console I/O is synchronized. A lock statement around the Console.* call might make it more obvious (for demo code)

If you want the other 2 threads to finish processing before calling Console.ReadKey() (blocking I/O call), you should call thread1.Join() and thread2.Join() before calling Console.ReadKey()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM