Reader Level:
ARTICLE

Multithreading with C#

Posted by Eranda Horanagama Articles | Multithreading in C# February 20, 2009
This article gives you an introduction to write multithreaded applications with c# and some basic ways for creating threads
  • 2
  • 0
  • 54517
Download Files:
 

Introduction

This article provides you a starting point for writing concurrent programs using threads in c# (every c# thread is typically delegates to the operating system). Threads allow you to develop more efficient applications synchronizing through the shared memory. And this article aims to wards the experienced programmers in c#. Other languages such as VB.net are using the same concept.

Why we should not use threads in our applications?

Creating and destroying a thread is costly process it takes processor time. Several things must be performed while creating

  1. Operating system must go in to kernel mode.
  2. Other threads must notify the new thread is created.
  3. Operating system must leave the kernel mode. Etc...

If you want to know about the kernel mode refer to http://www.codinghorror.com/blog/archives/001029.html

From the developers point of view

  1. Multithreading applications are hard to debug.
  2. And makes the application more complex.

Somehow it's up to developer to take challenge over the choice

Then why should we use threads?

So if this is such a costly process then why should we are using the threads...

Answer is within last couple of years processors had a rapid development especially on its speed. Nowadays a processor in the market is with a speed around 3GHz - 4GHz.when processor comes up to this level processor vendors such as Intel, AMD used to notified that processor can't be speeds up more and more with the environment they should use. Then they used to think about parallel processing, here's the point Hyper-threading technology comes in to action. Later they improved it to Dual Core then in to Core 2 Duo... I'm not going describe all those CPU architectures by here, and it's not what I except by this article as well. So my point is to "why should we use threads in our applications" and the answer is to use the maximum performance and of the above processors (advantage of parallel processing) we have to use the threads with our C# applications.

Using threads with C# application

There are several ways that we can use threads .net framework applications.

First I'll describe you how to use a dedicated thread within our application and later I'll describe you about using Thread pool and thread synchronization techniques as well. And I hope you have some knowledge of working with delegates at least why we are using delegates in C#. You can learn basics about delegates from here
http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx

Example: Using dedicated threads

C# code

class Program
    {
        static void Main(string[] args)
        {
            // create thread start delegate instance - contains the method to execute by the thread
            ThreadStart ts = new ThreadStart(run);
            // create new thread
            Thread thrd = new Thread(ts);
            // start thread
            thrd.Start();

            // makes the main thread sleep - let sub thread to run
            Thread.Sleep(1000);

            for (int t = 10; t > 0; t--)
            {
                Console.WriteLine("Main Thread value is :" + t);
                Thread.Sleep(1000);
            }

           Console.WriteLine("Good Bye!!!I'm main Thread");
           Console.ReadLine();

         }

        // this method executed by a separate thread
        static void run()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Sub Thread value is : " + i);
                Thread.Sleep(1000);
            }
            Console.WriteLine("Good Bye!!!I'm Sub Thread");
        }
   }

VB.net code

Module Module1

     Sub Main()

        'create thread start delegate instance - contains the method to execute by the thread
        Dim ts As ThreadStart = New ThreadStart(AddressOf run)
        ' create new thread
        Dim t As Thread
        t = New Thread(ts)
        ' start thread
        t.Start()

        ' makes the main thread sleep - let sub thread to run
        Thread.Sleep(1000)

        For i As Integer = 10 To 0 Step -1
            Console.WriteLine("Main thread value is" + i.ToString())
            Thread.Sleep(1000)
        Next i

        Console.WriteLine("Good Bye!!!I'm main Thread")
        Console.ReadKey()

    End Sub

    ' this method executed by a separate thread
    Sub run()

        For i As Integer = 0 To 10
            Console.WriteLine("Sub thread value is" + i.ToString())
            Thread.Sleep(1000)
        Next i
 
        Console.WriteLine("Good Bye!!!I'm Sub Thread")
   End Sub

 End Module

In the above code I have used a separate thread to execute my run method. When code executes you can see the output

multi.gif

Sub thread increases the value within its run method and the main thread decreases its value one after the other.

Here's the part we have created a new thread and assigned job to done.

            // create thread start delegate instance - contains the method to execute by the thread
            ThreadStart ts = new ThreadStart(run);
            // create new thread
            Thread thrd = new Thread(ts);
            // start thread
            thrd.Start();

In here the thread start delegate is optional and we can directly create the thread like this as well

            // create new thread
            Thread thrd = new Thread(run);
            // start thread
            thrd.Start();

Note: This is C# language shortcut and does not available with VB.net.

Make the thread a background thread

This thread remains runing even the main thread finishes it's job, to finalize all the threads when main thread dies you have to set the IsBackground property to true.

                // create new thread with ParameterizedThreadStart delegate instance
            Thread thrd = new Thread(run);
            // make the thread background
            thrd.IsBackground = true;
            // start thread with passing the parameters need
            thrd.Start();

Passing parameters to the threads

If you want to pass any parameters to the method which is used to execute by the new thread then you can use the ParamerizedThreadStart delegate instead of the ThreadStart delegate.

Example: Using ParameterizedThreadStart to invoke methods with parameters

ParameterizedThreadStart which we used to execute our method by a separate thread looks like this

public delegate void ParameterizedThreadStart(object obj);

So we have to change our run method like this (matches with the ParameterizedThreadStart)

         /* this method executed by a separate thread
         * this sholud be match with the ParameterizedThreadStart
         * (parameters must be passed as an object)
         */
        static void run(object args)
        {
            // cast our parameter
            int j = (int)args;

            for (int i = 0; i < j; i++)
            {
                Console.WriteLine("Sub Thread value is : " + i);
                Thread.Sleep(1000);
            }
            Console.WriteLine("Good Bye!!!I'm Sub Thread");
        }

Executing part is like this (please read the comments)

       // create new thread with ParameterizedThreadStart delegate instance
       Thread thrd = new Thread(new ParameterizedThreadStart(run));
       // start thread with passing the parameters need
       thrd.Start(10);

Assigning Thread pool class to get the job done

By using the threadpool class we can assign our work to done by a separate thread easily and this is the way recommended using whenever possible.

Example: Using Threadpool class

          // assign thread pool thread to do the job
       ThreadPool.QueueUserWorkItem(run);

If you want to pass any parameters to the method executing by the thread you can pass them as a second argument.like this for our run method with object parameter.

          // assign thread pool thread to do the job
       ThreadPool.QueueUserWorkItem(run,10);

Complete code

class Program
    {
        static void Main(string[] args)
        {
            // assign thread pool thread to do the job
            ThreadPool.QueueUserWorkItem(run,10);

            // makes the main thread sleep - let sub thread to run
            Thread.Sleep(1000);

            for (int t = 10; t > 0; t--)
            {
                Console.WriteLine("Main Thread value is :" + t);
                Thread.Sleep(1000);
            }
 
            Console.WriteLine("Good Bye!!!I'm main Thread");
           Console.ReadLine();

         }

        /* this method executed by a separate thread
         * this sholud be match with the WaitCallback
         * (parameters must be passed as an object)
         */
        static void run(object args)
        {
            // cast our parameter
            int j = (int)args;

            for (int i = 0; i < j; i++)
            {
                Console.WriteLine("Sub Thread value is : " + i);
                Thread.Sleep(1000);
            }
            Console.WriteLine("Good Bye!!!I'm Sub Thread");
        }
    }


Periodic operations from threads

If you want to perform any method call in a perodic order then you can use the Timer class.

Note : There are three timer classes availbale with .net framework class library one is in System namespace next is in System.Windows.Forms namespace and the last is in System.Threading namespace all of them are providing similar functinalties so please don't confuse them together,I'm talking here is about the System.Threading.Timer class

Example: Using Timer class

class Program
    {
        static void Main(string[] args)
        {
            // assign thread timer to do the job
            System.Threading.Timer thrdTimer = new Timer(run, 10, 0, 1000);

            // makes the main thread sleep - let sub thread to run
            Thread.Sleep(1000);

            Console.WriteLine("Good Bye!!!I'm main Thread");
            Console.ReadLine();

        }

         /* this method executed by a separate thread
         * this sholud be match with the TimerCallback
         * (parameters must be passed as an object)
         */
        static void run(object args)
        {
            // cast our parameter
            int j = (int)args;
          
            Console.WriteLine("Hi I'm executing by timer you passed " + j);
        }
    }

Here is the line we are assiging new timer to do the job,last parameter is the period to stay(in miliseconds) within the callbacks (here I have passed the 1000).

       // assign thread timer to do the job
       System.Threading.Timer thrdTimer = new System.Threading.Timer(run, 10, 0, 1000);

See and how much .net framework class library had made the developer life easier.

Here's the output by the above code

multi2.gif


You can see our run method is called perodically after every 1 second...

Here I gave you the first step of using multithreading with c#,later I'll describe you about the thread synchronization. Especially with the parrellel processing architechures we have to much concern about our mutithreading applications.

Better Coding
Cheers

COMMENT USING

Trending up