A Quick Guide to Multithreading in .NET

.Net Multithreading is when you run sections of code multiple times at the same time. For example, if you have an application and want one part to monitor files appearing in one directory and another part of the system to monitor the database. For this webpage, we will not be doing any quite as elaborate. This article is designed to give you a taster of what can be achieved. Threads can be modular functions or methods/functions from classes. The choice is yours.

The lock command is a keyword built into the .NET language. It is not part of any namespace. The command allows you to lock down part of the code to prevent any other thread from accessing the lock object. If you have resources that are used by multiple threads, it would be useful to create an object that is locked and other threads cannot run until the object has been released.

In my example below, I have a variable used by two threads to count the number of times all the threads are called. I create a LockKey, a simple bog standard object, and I lock that in the code where I am increasing the thread called an integer.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
    static int IFunctionCalled = 0;
    static object LockKey = new object();

    static void Main(string[] args)
    {
        // All parts of the System, including the main function, are a thread.
        Console.WriteLine("Current Thread Is = " + Thread.CurrentThread.ManagedThreadId.ToString());

        // Create instance of code to run concurrently.
        Thread Ten = new Thread(new ThreadStart(DisplayUpToTen));

        // You can name threads for identification later.
        Ten.Name = "DisplayUpToTen";
        Ten.Start();
            
        Thread Colour = new Thread(new ThreadStart(DisplayColour));

        // Priorities on threads can be Highest, AboveNormal, Normal, BelowNormal, Lowest
        Colour.Priority = ThreadPriority.Highest;

        // Threads do not start on their own.
        Colour.Start();
        Console.ReadKey();

        // Must terminate threads for the application to terminate properly.
        // If threads are still live, the application won't terminate.

        Ten.Abort();
        Colour.Abort();
    }

    static void DisplayColour()
    {
        Console.WriteLine("Current Thread Is = " + Thread.CurrentThread.ManagedThreadId.ToString());
        Random Rand = new Random();
        string[] Colours = {"Red","White","Gold","Green","Black","Blue","Brown","Pink","Orange"};

        while (0 == 0)
        {
            lock (LockKey)
            {
                IFunctionCalled++;
                Console.WriteLine("Colour = " + Colours[Rand.Next(Colours.GetUpperBound(0))]);
            }

            Thread.Sleep(500);
        }
    }

    static void DisplayUpToTen()
    {
        Console.WriteLine("Current Thread Is = " + Thread.CurrentThread.ManagedThreadId.ToString());
        Console.WriteLine("Current Thread Name = " + Thread.CurrentThread.Name);
        int i=1;
        while (i > 0)
        {
            lock (LockKey)
            {
                IFunctionCalled++;
                Console.WriteLine("{0}", i++);
                Console.WriteLine("Function Called : " + IFunctionCalled.ToString());
            }
            
            // Put thread to sleep to prevent clogging up the system.
            // Time is in milliseconds, so sleep for a full second.

            Thread.Sleep(1000);
        }
    }
}
}

Tags - .NET

Last Modified : June 2023


About... / Contact.. / Cookie...