Posted By: Phil Pennington | Nov 5th @ 8:53 AM | 33,084 Views | 12 Comments
Join Josh and Steve as they demonstrate how to use the new .NET4 Countdown event synchronization primitive in task coordination scenarios.

Countdown and related constructs are new with .NET4 and Visual Studio 2010.

Learn more about the System.Collections.Concurrent namespace and keep abreast of Parallel Computing tools and techniques via the Concurrency Dev Center.

See all videos in this series.

Rating:
0
1

It seems to me that in order to have a race condition ce.AddCount() should be inside lambda in the last code sample.

As long as ce.AddCount() is inside foreach loop on the main thread there won't be any race conditions, so adding "one for the host" before and then taking it out after the loop is kind of pointless.

 

Also, guys, _No Sound_ in SL3 on XP SP3 _again_.

 

Cheers,

Seva.

 

garrettvm
garrettvm
garrett

Good job! Thanks. I can't wait.

Seva, the problem is that the work item could complete asynchronously before the next item is even created on the main thread.  The main thread could add 1 count, kick off a work item, and that work item could complete and decrement the count prior to the main thread looping back around and adding to the count again.  That would cause the event to reach 0 even though additional work remained.

GrantB
GrantB
What the hell are we supposed to use man? Harsh language?

Are you saying Wait is triggered if the internal count is EVER zero? Such as the first lambda completing before the second time the main thread runs through the for loop?

 

If it triggers only if the count is currently zero, there shouldn't be a race becuase at the Wait the main thread has already added 1 for every element to be processed.

 

Yes... once zero, the event is set, such that anyone waiting on it will wake up.  And unless you call Reset on the event, once zero, attempting to increase the count will result in an exception.  This design actually helps to minimize races between threads changing the count (up or down) and threads waiting on the event.

Ah, "Once zero it cannot be incremented" - that's what was missing. Then it's all cool and dandy Smiley

I guess that the counter is NULL originally (if not set to any positive integer).

The whole "Don't forget to add one" is simply a hack.  Threaded programming is hard, and this tool keeps it that way, it's just not up to the task.

 

It would be much better if this primitive was not added at all than released in this form.

Yeah, that's a hack and is a bad one too. Why not to make "done adding" semantics explicit at least?

Then instead of add one before, remove one after there will be explicit call to ce.NoMoreCounterIncrements()

It doesn't guarantee that programmer won't forget to add it into the code, but that's one change to one code line as opposed to two (and it's a better "pattern" than the alternative).

 

Plus, if this primitive constructor accepted nested lambdas, then AddCounter() and NoMoreCounterIncrements() could be hidden from the programmer all together. Just declare what you want to spawn and how many of those in a nested lambda and happily wait for completion.

Agreed with sokhaty.  As it stands, how exactly is this different from a counting semaphore?

Microsoft Communities