Return to zero CountdownEvent
.net, c#, countdownevent, multithreading
Solution
Edit
public void Dispatch()
{
using (var ev = new CountdownEvent(1))
{
foreach (var task in <collection_of_tasks_to_start>)
{
ev.AddCount();
// start *task* here. Don't forget to pass *ev* to it!
}
ev.Signal();
ev.Wait();
}
}
// task code
void Handler(CountdownEvent ev)
{
try
{
// do task logic
}
finally
{
ev.Signal();
}
}
Why and how this works?
- If you haven't spawned any tasks
- nothing will happen and `Dispatch` will just finish normally.
- `ev.Signal` makes sure that once `ev.Wait` is called, initial value of the counter is `0` and `Wait` will not block execution
- If you spawned at least one task
- we have two cases to consider: fast- and slow-running tasks and understand how they affect execution at point where `ev.Wait()` is called.
- fast tasks, i.e. tasks that will complete before we reach the end.
- at the `ev.Wait()` the situation is equivalent to point 1.
- slow tasks, i.e. tasks that haven't completed before we reach the end.
- at the `ev.Wait()` the counter is not equal to `0` anymore, because of all the `ev.AddCount()` executed. Thus, execution will hold.
- once all running tasks complete (and have corresponding `ev.Signal()` lines executed) the counter drops to `0` and execution resumes exiting the routine
Original answer
You wrote:
I am performing an operation that will create an unknown number of child operations (not tasks or threads)
So what are they? You should do something like this:
CountdownEvent ev;
public void foo() {
ev = new CountdownEvent(1);
foreach ( <task in tasks_to_start> ) {
ev.AddCount();
// enter code here which starts your task
}
ev.Signal();
ev.Wait();
}
public static void youtTask(CountdownEvent ev) {
// some work
// ...
// after all is done
ev.Signal();
}
Problem
I'm trying to use a CountdownEvent to only allow threads to continue when the event's count is zero, however I would like the initial count to be zero. In effect I'd like a return to zero behaviour whereby the event is signalled whenever the count is zero and threads are made to wait whenever it's greater than zero. I can initialize a Countdown event with 0 initial count but when I try to add to the count I get InvalidOperationException "CountdownEvent_Increment_AlreadyZero" . Is there an alternative class or another way that I can use Countdown event in order to avoid this limitation?