Menu

C# Semaphore Cheat Sheet

20th November 2022 - c#, developer, Development, dotnetcore, Uncategorised

Here is a semaphore in action, used to throttle calls to a httpclient.

using System.Net.Http;

HttpClient _client=new(){
    Timeout=TimeSpan.FromSeconds(3)
};

SemaphoreSlim _semaphore1=new(1);
SemaphoreSlim _semaphore8=new(8);

var _myURL="https://blog.neilhighley.com";
var _numberOfCalls=100;

var callSite=async ()=>{
     try{
        var responseFromWebsite=await _client.GetAsync(_myURL);
        Console.WriteLine(responseFromWebsite.StatusCode);
    }catch(Exception e){
        Console.WriteLine(e.Message);
    }
};

var callSiteSemaphore1=async ()=>{
     try{
        await _semaphore1.WaitAsync();
        var responseFromWebsite=await _client.GetAsync(_myURL);
        Console.WriteLine(responseFromWebsite.StatusCode);
        _semaphore1.Release();
    }catch(Exception e){
        Console.WriteLine(e.Message);
    }
};

var callSiteSemaphore8=async ()=>{
     try{
        await _semaphore8.WaitAsync();
        var responseFromWebsite=await _client.GetAsync(_myURL);
        Console.WriteLine(responseFromWebsite.StatusCode);
        _semaphore8.Release();
    }catch(Exception e){
        Console.WriteLine(e.Message);
    }
};

IEnumerable<Task> CreateManyCalls(){
    for(var i=0;i<_numberOfCalls;i++){
        yield return callSite();
    }
};

// https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=net-7.0
IEnumerable<Task> CreateManyCallsSemaphore1(){
   
    for(var i=0;i<_numberOfCalls;i++){
        yield return callSiteSemaphore1();
    }
};

// https://learn.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=net-6.0
IEnumerable<Task> CreateManyCallsSemaphore8(){
   
    for(var i=0;i<_numberOfCalls;i++){
        yield return callSiteSemaphore8();
    }
};

Task.WaitAll(CreateManyCallsSemaphore8().ToArray());