Multithreading – SemaphoreSlim

By | 01/03/2023

In this post, we will see what is SemaphoreSlim and how we can use it.
But first of all, what is SemaphoreSlim?
From Microsoft web site:
“The SemaphoreSlim class represents a lightweight, fast semaphore that can be used for waiting within a single process when wait times are expected to be very short. SemaphoreSlim relies as much as possible on synchronization primitives provided by the common language runtime (CLR)”
In a nutshell, we can use SemaphoreSlim instance to limit the concurrent threads that can access to a resource in a multi-threaded environment. It is a lightweight alternative to Semaphore and, we should use it only when “wait times are expected to be very short” and for synchronization within a single app.
On the other hand, Semaphore permits to define named semaphores which can be system-wide and then, Semaphore is the better choice for cross-process synchronization.

We open Visual Studio, we create a Console Application and we add a class called Core:

[CORE.CS]

namespace SemaphoreSlimTest;

public class Core
{
    public void RunTest(string inputValue)
    {
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine(inputValue);
            Thread.Sleep(1000);
        }
    }
}


Then, we go to the Program file where we will add the code for calling three times the method RunTest:

[PROGRAM.CS]

using SemaphoreSlimTest;

Console.WriteLine("Testing Semaphore Slim");

Core objCore = new Core();

objCore.RunTest("A");
objCore.RunTest("B");
objCore.RunTest("C");


If we run the application, this will be the result:


We can see that everything works fine and now, we will change the Program file to use more Threads for calling the method RunTest:

using SemaphoreSlimTest;

Console.WriteLine("Testing Semaphore Slim");

Core objCore = new Core();

Thread firstThread = new Thread(() => objCore.RunTest("A"));
Thread secondThread = new Thread(() => objCore.RunTest("B"));
Thread thirdThread = new Thread(() => objCore.RunTest("C"));

firstThread.Start();
secondThread.Start();
thirdThread.Start();


If we run the application, this will be the result:


It works fine in fact, we can see that the system ran the Threads in the same time: FirstThread, SecondThread and ThirdThread.
Using SemaphoreSlim, we can define how many Threads can run simultaneously the method RunTest.
In order to do it, we have just to define a SemaphoreSlim in Core.cs and use it in the method RunTest:

namespace SemaphoreSlimTest;

public class Core
{
    // Definition of SemaphoreSlim
    // The value in the constructor is the number of Threads that can access at the code
    SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(2);
    public void RunTest(string inputValue)
    {
        try
        {
            _semaphoreSlim.Wait();
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(inputValue);
                Thread.Sleep(1000);
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            _semaphoreSlim.Release();
        }
    }
}



If we run the application, this is will be the result:


Instead, this is the result if we define that only 1 Thread can access at the code:


Finally, this is the result if we define that 3 Threads can access at the code:



Leave a Reply

Your email address will not be published. Required fields are marked *