SemaphoreSlim.Extend
1.0.1
dotnet add package SemaphoreSlim.Extend --version 1.0.1
NuGet\Install-Package SemaphoreSlim.Extend -Version 1.0.1
<PackageReference Include="SemaphoreSlim.Extend" Version="1.0.1" />
<PackageVersion Include="SemaphoreSlim.Extend" Version="1.0.1" />
<PackageReference Include="SemaphoreSlim.Extend" />
paket add SemaphoreSlim.Extend --version 1.0.1
#r "nuget: SemaphoreSlim.Extend, 1.0.1"
#:package SemaphoreSlim.Extend@1.0.1
#addin nuget:?package=SemaphoreSlim.Extend&version=1.0.1
#tool nuget:?package=SemaphoreSlim.Extend&version=1.0.1
SemaphoreSlim Extensions for Argument-Based Concurrency Control
Overview
This library provides custom extension methods for SemaphoreSlim to enable concurrent execution control per specific argument passed at runtime. It is useful when you need to limit concurrency based on distinct values, such as user IDs, request types, or any other key.
Features
- Argument-Based Concurrency Control: Ensures that tasks with the same key execute with limited concurrency while allowing unrelated tasks to proceed independently.
- Thread-Safe Implementation: Uses
SemaphoreSliminternally with a dictionary to manage semaphores for different keys. - More Readable Code Than Original Semaphore: Write your code as argument to
SemaphoreSlimWaitAsyncmethod without repeating try/finally block to release it. - Asynchronous Support: Supports
async/awaitto avoid blocking threads. - Automatic Cleanup: Removes semaphores when no longer needed to prevent memory leaks.
Installation
Add the library to your .NET project via NuGet (if published) or include the source files in your solution.
Install-Package SemaphoreSlim.Extend
Usage
Basic Example
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
// Allow only one concurrent Execution per product_Id, user_Id, any unique argument
static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
const string product1Id = "proudct1";
const string product2Id = "proudct2";
public static async Task Main(string[] args)
{
System.Console.WriteLine("");
Print($"Start Time ");
System.Console.WriteLine("");
System.Console.WriteLine(" ********************************************* ");
Stopwatch sw = Stopwatch.StartNew();
var tasks = Enumerable.Range(0, 10).Select(x =>
{
if (x % 2 == 0)
{
return semaphoreSlim.WaitAsync(product1Id, async () =>
{
Print($"ProductId = {product1Id}, {x.ToString()}");
await Task.Delay(1000);
});
}
else
{
return semaphoreSlim.WaitAsync(product2Id, async () =>
{
Print($"ProductId = {product2Id}, {x.ToString()}");
await Task.Delay(1000);
return "Dummy Method Output";
});
}
}).ToArray();
await Task.WhenAll(tasks);
sw.Stop();
Print($"End Time ");
System.Console.WriteLine(" ********************************************* ");
System.Console.WriteLine("");
System.Console.WriteLine($"Elapse Time for 10 requests with 2 different productIds = {sw.Elapsed}");
System.Console.WriteLine("");
}
private static Timer timer = new((data) => System.Console.WriteLine("\r\n----------- Allowed Concurrent Code Execution Per ProductId -----\r\n"), null, 0, 1000);
private static void Print(string output)
{
System.Console.WriteLine(output + " ==> " + DateTime.Now.ToString());
}
}
Benefits
- Improved Performance: Prevents overloading shared resources while allowing parallel execution.
- Granular Control: Limits concurrency at the argument level rather than globally.
- Scalability: Suitable for multi-user, multi-tenant, or high-throughput applications.
Contributions
Contributions, issues, and feature requests are welcome. Please submit them via GitHub Issues.
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SemaphoreSlim.Extend:
| Package | Downloads |
|---|---|
|
QuartzNET.Extend
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.