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());