RSS

Limiting Number of Concurrent Threads With SemaphoresSlim

02 Feb

Coordinating concurrent actions for a predictable outcome or in one word synchronization with concurrent programming is a sometimes a challenging task. There are three main ways of achieving this.

  1. Exclusive locking
  2. Non-exclusive locking
  3. Signaling

Problem
I was working on an external image downloader service which heavily used C# async processing for downloading thousands of images through internet. Downloader tool was too fast due to async nature so there were occasional failures at runtime due to excessive use of network and exceeding resource capacity in the server.

Using Non-exclusive locking for limiting concurrency
Nonexclusive locking is useful in limiting concurrency where preventing too many threads from executing particular function or section in your code at once.  I used SemaphoreSlim which lives in System.Threading namespace. There are two  similar versions of this construct which are Semaphore and  SemaphoreSlim. However latter has been introduced in .NET 4 and has been optimized for performance. So we should better use it.

So how does SemaphoreSlim limits concurrency?
The way semaphore slim work is extremely simple to understand as shown in diagram below.semaphoreslim

The way it work is analogous to a hall that has “N” number of seats for people and has two does to enter and exit. When hall filled with people people has to wait near entrance door until someone goes out from exit door. Maximum number of threads that can be active in semaphore will be limited. It is configurable in SemaphoreSlim constructor. I have also moved this to a configurable value.

private SemaphoreSlim _mysemaphoreSlim = new SemaphoreSlim(Configuration. MaxConcurrency);

Following is very simple method shell that you might need to limit concurrency.

private async Task<bool> AsyncMethod()
{
    this._ mysemaphoreSlim.Wait();

    /* Do the other cool things here, Only N number
    of threads can be between Wait and Release */

    /* After finishing your work, call release this will
    allow to enter another thread if any waiting to execute */

    this._mysemaphoreSlim.Release();
}

 

You could also use

 mysemaphoreSlim.WaitAsync()

if you need waiting threads to be utilized as non-blocking synchronization.

Advertisements
 
Leave a comment

Posted by on February 2, 2016 in .NET, C#

 

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: