Created
September 17, 2018 04:27
-
-
Save mebjas/222d76dbb51250c938d83331720bd469 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Semaphore Class with variable concurrency | |
/// </summary> | |
public class SemaphoreFat : IDisposable | |
{ | |
/// <summary> | |
/// Maximum capacity of this semaphore | |
/// </summary> | |
private int maxCapacity; | |
/// <summary> | |
/// Current capacity of this semaphore | |
/// </summary> | |
private int capacity; | |
/// <summary> | |
/// internal semaphore object instance | |
/// </summary> | |
private SemaphoreSlim sem; | |
/// <summary> | |
/// Initializes a new instance of the <see cref="SemaphoreFat" /> class. | |
/// </summary> | |
/// <param name="initialCapacity"></param> | |
/// <param name="maxCapacity"></param> | |
public SemaphoreFat(int initialCapacity, int maxCapacity) | |
{ | |
if (capacity > maxCapacity) | |
{ | |
throw new InvalidOperationException("Capacity cannot be greater than Max"); | |
} | |
this.maxCapacity = maxCapacity; | |
this.capacity = initialCapacity; | |
this.sem = new SemaphoreSlim(this.maxCapacity); | |
this.updateHeldCapacity(this.capacity, this.maxCapacity); | |
} | |
/// <summary> | |
/// Blocks the current thread until it can enter the <see cref="SemaphoreFat"/> | |
/// </summary> | |
public void Wait() | |
{ | |
this.sem.Wait(); | |
} | |
/// <summary> | |
/// Releases the <see cref="SemaphoreFat"/> object once. | |
/// </summary> | |
public void Release() | |
{ | |
this.sem.Release(); | |
} | |
/// <summary> | |
/// Updates the capacity of the semaphore. If it's a capacity increase request | |
/// This thread shall be blocked until that happens | |
/// </summary> | |
/// <param name="newCapacity">new capacity of the semaphore</param> | |
public void Update(int newCapacity) | |
{ | |
if (newCapacity <= 0) | |
{ | |
throw new InvalidOperationException("Capacity cannot be less than or equal to zero;"); | |
} | |
if (newCapacity > this.maxCapacity) | |
{ | |
throw new InvalidOperationException("Capacity cannot be greater than or max capacity;"); | |
} | |
this.updateHeldCapacity(newCapacity, this.capacity); | |
this.capacity = newCapacity; | |
} | |
/// <summary> | |
/// Disposes the object | |
/// </summary> | |
public void Dispose() | |
{ | |
try | |
{ | |
this.sem.Dispose(); | |
} | |
catch | |
{ | |
//// | |
} | |
} | |
/// <summary> | |
/// Method to update the capacity of this semaphore | |
/// </summary> | |
/// <param name="newCapacity">new capacity requested</param> | |
/// <param name="oldCapacity">older capacity</param> | |
private void updateHeldCapacity(int newCapacity, int oldCapacity) | |
{ | |
int delta = newCapacity - oldCapacity; | |
if (delta < 0) | |
{ | |
for (int i = 0; i < -delta; i++) | |
{ | |
this.sem.Wait(); | |
} | |
} | |
else | |
{ | |
for (int i = 0; i < delta; i++) | |
{ | |
this.sem.Release(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment