I have asked this question before - but I have spent some time thinking about it and have implemented a working version.
Overview
1) Threads are being created to perform a certain task.
2) Only one thread can perform the task at a time.
3) Each thread performs the exact same task. (Does a bunch of checks and validations on a system)
3) The threads are being created faster than the task can be performed. (I have no control over the thread creation)
Result is that overtime I get a backlog of threads to perform the task.
What I have implemented goes as follows
1) Thread checks to see how many active threads there are.
2) If there are 0 threads it is marked to PerformTask and it starts the task
3) If there is 1 thread it is marked to PerformTak and it blocks
4) If there is more than 1 thread the thread is not marked to PerformTasks and just dies
The idea is that if there is a thread waiting to perform the task already I just kill the thread.
Here is the code that I came up with
bool tvPerformTask = false;
ivNumberOfProcessesSemaphore.WaitOne();
if (ivNumberOfProcessesWaiting == 0 ||
ivNumberOfProcessesWaiting == 1)
{
ivNumberOfProcessesWaiting++;
tvPerformTask = true;
}
ivNumberOfProcessesSemaphore.Release();
if (tvPerformTask)
{
//Here we perform the work
ivProcessSemaphore.WaitOne();
//Thread save
ivProcessSemaphore.Release();
ivNumberOfProcessesSemaphore.WaitOne();
ivNumberOfProcessesWaiting--;
ivNumberOfProcessesSemaphore.Release();
}
else
{
//we just let the thread die
}
The problem that I have is not that it doesn't work it is just that I do not find the code elegant specifically I am not very happy that I need 2 semaphores an integer and a local flag to control it all. If there a way to implement this or pattern that would make the code simpler.