Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

The .NET4 Countdown Synchronization Primitive

Download

Right click “Save as…”

  • WMV (WMV Video)
  • MP3 (Audio only)
  • MP4 (iPhone, Android)
  • Mid Quality WMV (Lo-band, Mobile)
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.

Tags:

Follow the Discussion

  • 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.

     

  • garrettvmgarrettvm 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.

  • Grant BoyleGrantB 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?

  • re: "how exactly is this different from a counting semaphore?"

     

    In a sense, it's almost the opposite.  With a semaphore, you block while the count is zero; with a countdown event, you block until it's zero.

  • re: "The whole "Don't forget to add one" is simply a hack"

     

    Thanks for the feedback.   I understand that viewpoint, though I personally don't view this as a hack at all.  CountdownEvent is used to keep track of a number of outstanding work items, and there's nothing at all that says one of those items can't be on the current thread, nor is there any reason all of the operations need to be homogenous in workload.  In this example, one of the work items is the work of spinning off all other work items; since we know about that piece of work when we start, we initialize the CountdownEvent to 1, and when we're done with that piece of work, as with all other pieces of work tracked by the event, we signal.

  • As I see it, a counting semaphore is a form of throttle. This primitive is not related.

     

    For me, the example code scenario is very familiar and this replaces the array of wait handles that I usually have to maintain when spinning up work items. I must admit to frowning at the 'hack' as it looked easy to forget, and like an after thought. There could be something like a FinishedAdding() method (just sets an initial handle) just to emphasise the requirement, or maybe not.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.