Multithreading_Library 2.4.4
dotnet add package Multithreading_Library --version 2.4.4
NuGet\Install-Package Multithreading_Library -Version 2.4.4
<PackageReference Include="Multithreading_Library" Version="2.4.4" />
paket add Multithreading_Library --version 2.4.4
#r "nuget: Multithreading_Library, 2.4.4"
// Install Multithreading_Library as a Cake Addin #addin nuget:?package=Multithreading_Library&version=2.4.4 // Install Multithreading_Library as a Cake Tool #tool nuget:?package=Multithreading_Library&version=2.4.4
Multithreading_Library
This library provides utilities to handle various multithreading scenarios in .NET applications. It contains the following classes:
- OneWriteMultiRead: This class resolves performance limitations when transferring data between threads.
The main challenge with multiple readers is that they can block the writer from updating a variable, leading to contention.
OneWriteMultiRead
allows reader threads to access the shared data with minimal performance impact while enabling an arbitrary number of threads to read the current value simultaneously.
// Example usage
OneWrite_MultiRead<decimal> sharedDecimal = new OneWrite_MultiRead<decimal>(100);
/// Reader threads
decimal t = sharedDecimal.Value;
// Writer thread
sharedDecimal.Value = VALUE1;
Please note that for mutable and reference types it is recommended to enable DeepClone (Default) this makes objects sort of threadsafe by copying them.
Please note that each read value is then no longer Synchronized in between the threads. For immutable types such as simple data types (int, bool, ...) DeepCloning can be disabled.
Custom types and structs should implement the IDeepCloneable<T>
interface when deepcopy is enabled for improved performance. Here's an example:
[Serializable]
internal class CloneableObject : IDeepCloneable<CloneableObject>
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Clothes { get; set; } = new List<string>();
public CloneableObject DeepClone()
{
// Create a deep copy of the object
var clone = new CloneableObject
{
Id = this.Id,
Name = new string(this.Name.ToCharArray()) // Deep copy the string
};
foreach (string cloth in Clothes)
{
clone.Clothes.Add(new string(cloth.ToCharArray()));
}
return clone;
}
}
[Serializable]
internal struct CloneableStruct : IDeepCloneable<CloneableStruct>
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Clothes { get; set; }
public CloneableStruct DeepClone()
{
// Create a deep copy of the object
var clone = new CloneableStruct
{
Id = this.Id,
Name = new string(this.Name.ToCharArray()),
Clothes = new List<string>()
};
foreach (string cloth in Clothes)
{
clone.Clothes.Add(new string(cloth.ToCharArray()));
}
return clone;
}
}
You can also access the Cloning Extension directly as suggested in the xunit test:
[Fact]
public void DeepClone_CloneableType()
{
// Arrange
var original = new CloneableObject()
{
Id = 1,
Name = "Original",
Clothes = new() { "Pant", "Socks" }
};
// Act
var cloned = Cloning.DeepClone(original);
// Assert
Assert.NotNull(cloned);
Assert.NotSame(original, cloned); // Ensure it's a different instance
Assert.Equal(original.Id, cloned.Id);
Assert.Equal(original.Name, cloned.Name);
// change values to make sure we are not destroying things
cloned.Name = "Clone";
cloned.Id = 2;
cloned.Clothes.AddRange(new[] { "Shirt", "Glasses" });
// Ensure that the string is deeply copied
Assert.NotSame(original.Name, cloned.Name);
Assert.NotEqual(original.Id, cloned.Id);
Assert.NotEqual(original.Name, cloned.Name);
Assert.NotEqual(original.Clothes.Count, cloned.Clothes.Count);
}
The Cloning Method is Based on Baksteen.Extensions.DeepCopy Published under MIT-License
IDLocks
: This class provides locks that are accessible through a dictionary. This allows specific tasks, names, or other entities to be locked individually, enabling finer control over thread synchronization.
// Example usage
IDLocks<int> idLocks = new IDLocks<int>();
var lockObject = idLocks.ObtainLockObject(5);
RequestIDGenerator
this class returns an incremental, threadsafe id which can be used to identify requests. EG for a websocket. The function rolls over to 0 at int.MaxValue
// Example usage
RequestIDGenerator idGenerator = new RequestIDGenerator();
int id = idGenerator.GetNextRequestId()
AsyncHelper
: This class provides utilities to run an asynchronous Task and wait for the result in a synchronous method. It should be used with caution as it can lead to potential deadlocks. Whenever possible, prefer keeping async code all the way up the call stack.
// Example usage
int parameter = 5;
int result = AsyncHelper.RunSync(async () => await SomeAsyncMethod(parameter));
Caching
: The library includes examples of lightweight caching mechanisms.LazyCache\<T\>
: A simple cache that holds a value for a specified timespan. After the timespan expires, it returns null or default.// Example usage LazyCache<int?> numberCache = new (TimeSpan.FromMinutes(5)); // values are valid for 5 Minutes numberCache.Value = 42; // Setting a value int? cachedNumber = numberCache.Value; // Retrieving the value if (cachedNumber == null) // set new value if cache has expired cachedNumber = FetchReason("Life");
LazyCacheDictionary\<TKey, TValue\>
: A thread-safe, lazy-loading cache dictionary with expiration for each key. It supports automatic cleanup of expired entries.// Example usage // individual item validity time = 5 Minutes // cache cleanup interval = 1 Hour LazyCacheDictionary<string, int?> dictionaryCache = new (TimeSpan.FromMinutes(5), TimeSpan.FromHours(1)); dictionaryCache.Set("key1", 100); // Adding a value int? value = dictionaryCache.Get("key1"); // Retrieving a value if (value == null) // set new value if cache has expired dictionaryCache.Set("Life", 42);
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net6.0
- Microsoft.Extensions.Caching.Memory (>= 8.0.0)
- Microsoft.VisualStudio.Threading (>= 17.9.28)
-
net7.0
- Microsoft.Extensions.Caching.Memory (>= 8.0.0)
- Microsoft.VisualStudio.Threading (>= 17.9.28)
-
net8.0
- Microsoft.Extensions.Caching.Memory (>= 8.0.0)
- Microsoft.VisualStudio.Threading (>= 17.9.28)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Multithreading_Library:
Package | Downloads |
---|---|
Chia-Client-API
CHIA-RPC is a C# Nuget library that allows developers to easily communicate with the Chia client. It provides a wrapper for making requests, sending transactions, and minting, making it a versatile tool for interacting with the Chia blockchain. With CHIA-RPC, you can easily integrate Chia functionality into your C# projects. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.4.4 | 65 | 11/13/2024 |
2.4.2 | 106 | 7/16/2024 |
2.4.1 | 138 | 4/10/2024 |
2.4.0 | 101 | 4/9/2024 |
2.3.0 | 117 | 4/8/2024 |
2.2.0 | 117 | 4/4/2024 |
2.1.1 | 118 | 4/4/2024 |
2.1.0 | 114 | 4/4/2024 |
2.0.0 | 113 | 3/27/2024 |
1.9.0 | 134 | 3/15/2024 |
1.8.0 | 136 | 1/19/2024 |
1.7.0 | 103 | 1/19/2024 |
1.6.0 | 150 | 1/4/2024 |
1.5.0 | 147 | 12/13/2023 |
1.4.0 | 113 | 12/12/2023 |
1.3.0 | 136 | 12/5/2023 |
1.2.1 | 213 | 12/1/2023 |
1.2.0 | 121 | 12/1/2023 |
1.1.1 | 167 | 7/4/2023 |
1.1.0 | 153 | 7/4/2023 |
1.0.1 | 283 | 1/25/2023 |
1.0.0 | 298 | 1/9/2023 |
2.4.4
- added update cleanup timespan to cache
- added read only properties to get the content of LazyCacheDictionary
- Added a Tryclone function to lazycache, which improves working with reference types
2.4.2
- implemented Exists to check if a valid cache entry is present in Lazycachedictionary
2.4.1
- AsyncReaderWriterLock:added optional Timeout and cancellation token
2.4.0
- upate and merge Blockdebouncer and ExclusiveExecutiondebouncer
- Inplement AwaitableSignal
2.3.0
Added an implementation of asyncReaderWriterLock
2.2.0
- added ExclusiveExecutionDebouncer
2.1.1
- added TryGet for uniquely identified classes and structs
2.1.0
- Update ConcurrentHashset in order to allow value updating
- Remove has been renamed to TryRemove
2.0.0
- implement new debouncers
- clean all code by fixing compiler warnings
- update xml comments