locked
Compact Framework 2.0 and Multi-threading ? RRS feed

  • Question

  • Hi there -

    In a nut-shell - Is creating multiple threads to perform multiple tasks - expected to decrease the execution time or there will NOT be significant difference?

    I have following code snippet. In this code - I did run two scenarios -

    Scenario 1 - there are no threads created and the sequence of calling is as follows....

                InitializeComponent();
                System.Diagnostics.Debug.WriteLine("Time Taken in InitializeComponent = [" + (Environment.TickCount - StTime) + "]");
                CreateForms();
                CreateF2();

    The time taken to complete the execution  = 1733ms.

    Scenario 2 - Create two threads to execute CreateForms and CreatF2 in two different threads. I assume here that creating these forms in two threads would be done in parallel and if not exactly 1/2 -- atleast I would expect a reduction in the execution time.

    Strangely it is observed that time is increased to 1986ms. Any inputs or improvements suggested ?

    thanks and regards
    Santosh

    Following is the smaller code snippet.

    ----------------------------------
                StTime = Environment.TickCount;

                workerThread = new Thread(BackgroundProcessing);
                workerThread.IsBackground = true;
                workerThread.Priority = ThreadPriority.AboveNormal;
                workerThread.Start();

                thrd1 = new Thread(Tpc1);
                thrd1.IsBackground = true;
                thrd1.Priority = ThreadPriority.AboveNormal;
                thrd1.Start();
               
                InitializeComponent();
                System.Diagnostics.Debug.WriteLine("Time Taken in InitializeComponent = [" + (Environment.TickCount - StTime) + "]");
                //CreateForms();
                //CreateF2();
                while (threadDone == false || t1_done == false)
                {
                    System.Diagnostics.Debug.WriteLine("Sleeping !!");
                    Thread.Sleep(10);
                }
                System.Diagnostics.Debug.WriteLine("Time Taken in CreateForms = [" + (Environment.TickCount - StTime) + "]");
    ----------------------------------------

    Complete Source - is as below.
    -------------------------------
    {
        public partial class Form1 : Form
        {
            private bool processingDone = false;
            private Thread workerThread,thrd1;
            private TestForm myTestForm;
            private Testf2 testf2;

            private long StTime = 0;
            bool threadDone = false, t1_done = false;

            public Form1()
            {
                StTime = Environment.TickCount;

                workerThread = new Thread(BackgroundProcessing);
                workerThread.IsBackground = true;
                workerThread.Priority = ThreadPriority.AboveNormal;
                workerThread.Start();

                thrd1 = new Thread(Tpc1);
                thrd1.IsBackground = true;
                thrd1.Priority = ThreadPriority.AboveNormal;
                thrd1.Start();
               
                InitializeComponent();
                System.Diagnostics.Debug.WriteLine("Time Taken in InitializeComponent = [" + (Environment.TickCount - StTime) + "]");
                //CreateForms();
                //CreateF2();
                while (threadDone == false || t1_done == false)
                {
                    System.Diagnostics.Debug.WriteLine("Sleeping !!");
                    Thread.Sleep(10);
                }
                System.Diagnostics.Debug.WriteLine("Time Taken in CreateForms = [" + (Environment.TickCount - StTime) + "]");
            }

            private void CreateForms ()
            {
                System.Diagnostics.Debug.WriteLine("Test Form Started = " + threadDone.ToString());
                myTestForm = new TestForm();
                threadDone = true;
                System.Diagnostics.Debug.WriteLine("Test Form done = " + threadDone.ToString());
            }

            private void CreateF2()
            {
                t1_done = false;
                System.Diagnostics.Debug.WriteLine("TestF2 Started = " + threadDone.ToString());
                testf2 = new Testf2();
                t1_done = true;
                System.Diagnostics.Debug.WriteLine("Testf2 Done = " + threadDone.ToString());
            }

            private void button1_Click(object sender, EventArgs e)
            {
                button1.Enabled = false;
                processingDone = false;
                threadDone = false;

      /*
                workerThread = new Thread(BackgroundProcessing);
                workerThread.IsBackground = true;
                workerThread.Priority = ThreadPriority.AboveNormal;
                workerThread.Start();
     */
            }

            private void button2_Click(object sender, EventArgs e)
            {
                workerThread.Abort();
                button1.Enabled = true;
            }

            private void Tpc1()
            {
                try
                {
                    //while (!processingDone)
                    //{
                    //    ;
                    //}

                    CreateF2 ();
                }
                catch (ThreadAbortException e)
                {
                    MessageBox.Show(e.Message);
                }
                finally
                {
                    // This deinitialization code must always be executed,
                    // so be sure to put it in a finally clause
                    //Thread.Sleep(2000);
                }
            }

            private void BackgroundProcessing()
            {
                try
                {
                    //while (!processingDone)
                    //{
                    //    ;
                    //}

                    CreateForms ();
                }
                catch (ThreadAbortException e)
                {
                    MessageBox.Show(e.Message);
                }
                finally
                {
                    // This deinitialization code must always be executed,
                    // so be sure to put it in a finally clause
                    //Thread.Sleep(2000);
                }
            }
        }
    }
    -------------------------------
    • Changed type warrentang Thursday, September 24, 2009 1:58 AM
    Friday, September 18, 2009 10:53 AM

Answers

  • Hi there -

    In a nut-shell - Is creating multiple threads to perform multiple tasks - expected to decrease the execution time or there will NOT be significant difference?
    The universally correct answer to this is "It depends...". The actual execution time is going to depend on what it is that you are multithreading. Threads that contain a lot of IO blocking calls will benefit. Threads that are purly computationally intensive on a single core device may run slower.
    Create two threads to execute CreateForms and CreatF2 in two different threads. I assume here that creating these forms in two threads would be done in parallel and if not exactly 1/2 -- atleast I would expect a reduction in the execution time.

    To be done in parallel the executing device would need multiple cores. Otherwise only one thread will execute at a time. Even with multiple cores there are other thread on the device that must execute, and they will influence the amoun of execution time that your threads get.

    You should also consider that starting a new thread does not cause it to instantly run. Starting a threads marks the thread as available to the thread scheduler as a canidate for thread that will get CPU bandwidth.

    If you want to have more control over thread execution you need t look into the concept of a mutex, semaphore, and other multithreading concepts. You will find implementations of these operating system objects on almost all operating systems. If you were using these objects then your while loop could be replaced with a single call that would susped execution until the other threads are complete. Though on a side note, your while loop can't be used to accurately measure the execution time of the other threads. After the other threads terminate your main thread may not be the next thread to immediatlely execute. So included in your timing is the time it takes for the main thread to get control again.


    Joel Ivory Johnson
    • Marked as answer by warrentang Thursday, September 24, 2009 1:58 AM
    Friday, September 18, 2009 5:22 PM