Why Multithreading Slow in C #

When this code runs and all three threads are running, mapping the random number to labels becomes slow. Whereas when one or two threads stop, the processing becomes faster. Why is this?

namespace MultiThreadingCheckBox
{
    public partial class Form1 : Form
    {
        Thread t1, t2, t3; 
        public Form1()
        {
            InitializeComponent();
        }

    private void Form1_Load(object sender, EventArgs e)
    {
        t1 = new Thread(new ThreadStart(DoWork1));
        t2 = new Thread(new ThreadStart(DoWork2));
        t3 = new Thread(new ThreadStart(DoWork3));
        t1.Start();
        t2.Start();
        t3.Start();
    }

    private void DoWork1()
    {
        Random p = new Random(); 
        while (true)
        {
            label1.Invoke(new MethodInvoker(delegate { label1.Text = p.Next(1, 1000).ToString(); })); 
        }
    }

    private void DoWork2()
    {
        Random p = new Random();
        while (true)
        {
            label2.Invoke(new MethodInvoker(delegate { label2.Text = p.Next(1, 1000).ToString(); }));
        }
    }

    private void DoWork3()
    {
        Random p = new Random();
        while (true)
        {
            label3.Invoke(new MethodInvoker(delegate { label3.Text = p.Next(1, 1000).ToString(); }));
        }
    }
    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox1.Checked == true)
        {
            t1.Suspend();
            label1.Invoke(new MethodInvoker(delegate { label1.Text = "I am stopped"; }));
        }
        else
            t1.Resume(); 
    }

    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox2.Checked == true)
        {
            t2.Suspend();
            label2.Invoke(new MethodInvoker(delegate { label2.Text = "I am stopped"; }));
        }
        else
            t2.Resume(); 
    }

    private void checkBox3_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox3.Checked == true)
        {
            t3.Suspend();
            label3.Invoke(new MethodInvoker(delegate { label3.Text = "I am stopped"; }));
        }
        else
            t3.Resume(); 
    }
}

      

}

+3


source to share


3 answers


First of all, because the whole thread process continues to loop every time the thread waits to execute.

The second point is the system configuration. If you have a multi-core system, then each core can execute one thread, so if 4 cores then three threads will execute in parallel, but if one core or two cores, then the thread must wait for execution.



The third point is that every time you use invoke on the label to update each switch context to the UI thread, to also reduce and impact application performance.

+5


source


First of all, displaying stuff on a form requires the UI thread to do the work.
So, when you call (), you are making a synchronous call on the UI thread to change the display.
This means that the thread posts a message to the UI thread and goes to sleep until it is indicated that it has finished.

To avoid this use BeginInvoke

this will send an asynchronous message to the UI thread and will not pause the thread.



Now the second question is if you are using more threads than you have kernels.
So the processor cannot run it in parallel for physical reasons, it doesn't have another core to do it with. So it's not true parallelism that apart from the threads going to sleep, you get slow performance.

+7


source


As an aside, since Yochai Timmer and dotnetstep have already explained why this is slow, I would also like to suggest using Tasks instead of creating your own threads. Tasks will manage the thread pool for you and will probably do it more efficiently than you can actually handle without putting too much effort into it.

Obviously, you've written a sample application, so you probably already know about the tasks. In this case, I agree with Yochai, you should definitely use BeginInvoke to access the UI asynchronously.

0


source







All Articles