My application manages a complex concurrency scenario, where maximum concurrency for certain methods is managed across multiple processes. Through a manegement GUI the maximum concurrency for a given method can be adjusted up and down.
There is 1 parent process in charge of concurrency. This parent process spawns child processes that must respect the concurrency limitations.
I have implemented this scenario using named semaphores:
- The parent process on startup instantiates a named semaphore with an initial Count = the current max concurrency and a maximum Count of som big number (10000)
- When a child process wants to run it instantiates a semaphore using the same name and issues a WaitOne(). When WaitOne() returns the process method runs and calls Release on the semaphore instance when done (or faulted). This is implemented in a Disposable pattern.
- If a user in the GUI increases concurrency, the master process will call Release() on the named semaphore accordingly
- If a user decreases concurrency the master process issues WaitOne() calls on the semaphore accordingly
All this actually runs very nicely and is very lightweight compared to any other cross-process implementation I can think of. But there is 1 sour grape in the wine: If somebody kills a child process (for instance using task manager) the Disposable() pattern mentioned above does not Release() the named semaphore and the entire mechanism is then 'one off'.
And here comes the question: Is there any way to enumerate named semaphores AND adjust their release Counts?