提出问题提出问题
 

已答复When to use ManualResetEventSlim

  • 2009年6月26日 3:45Joe AlbahariMVP用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hi there

    It says in the PFX Blog that ManualResetEventSlim (and SemaphoreSlim) are optimized for short waiting times.

    If you anticipate long waiting times, is the best practice to use ManualResetEvent(Fat)? What's the performance cost of using the slim event with a long wait? I've noticed from its implementation that it first spins for a while and then calls Monitor.Wait so maybe it's OK with long waits.

    Also, why is there no AutoResetEventSlim?

    Joe
    Write LINQ queries interactively - www.linqpad.net

答案

  • 2009年6月26日 16:03Josh PhillipsMSFT用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    Hi Joe,

    Thanks for the great questions.  Yes, if you know there will be really long wait times you might as well use a full-blown MRE from the get-go.  Why waste any time spinning at all?  If you're sure the wait times will be small or feel like they might be somewhere in between, you should use an MRES. 

    Regarding perf: If you were using a MRES in a vacuum, the performance of using it compared to an MRE with a long wait would be roughly the same.  The true performance benefit is when you have other threads waiting to consume CPU resources.  Spinning, of course, eats up valuable CPU time that other threads in your app, or system, could be using.  The point is that calling Monitor.Wait transitions into the kernel which can use thousands of cycles.  If you only expect to wait for only, say, 200 cycles, then using up thousands of cycles to do give up the thread for only a short period of time is wasteful. 

    As for AutoResetEventSlim.. is there a scenario for which you need it?  Truth be told, creating an AutoResetEvent is quite difficult and the use cases are very limited so we prioritized our efforts elsewhere.  If there's a real need for you to have one, I'd love to hear it so we could consider creating one!

    Thanks!

    Josh

    PS - I will suggest to the BCL team that we rename ManualResetEvent to ManualResetEventFat immediately!

全部回复

  • 2009年6月26日 16:03Josh PhillipsMSFT用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    Hi Joe,

    Thanks for the great questions.  Yes, if you know there will be really long wait times you might as well use a full-blown MRE from the get-go.  Why waste any time spinning at all?  If you're sure the wait times will be small or feel like they might be somewhere in between, you should use an MRES. 

    Regarding perf: If you were using a MRES in a vacuum, the performance of using it compared to an MRE with a long wait would be roughly the same.  The true performance benefit is when you have other threads waiting to consume CPU resources.  Spinning, of course, eats up valuable CPU time that other threads in your app, or system, could be using.  The point is that calling Monitor.Wait transitions into the kernel which can use thousands of cycles.  If you only expect to wait for only, say, 200 cycles, then using up thousands of cycles to do give up the thread for only a short period of time is wasteful. 

    As for AutoResetEventSlim.. is there a scenario for which you need it?  Truth be told, creating an AutoResetEvent is quite difficult and the use cases are very limited so we prioritized our efforts elsewhere.  If there's a real need for you to have one, I'd love to hear it so we could consider creating one!

    Thanks!

    Josh

    PS - I will suggest to the BCL team that we rename ManualResetEvent to ManualResetEventFat immediately!
  • 2009年6月26日 16:44Joe AlbahariMVP用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Thanks, Josh.

    I've never needed an AutoResetEventSlim - the fat version has always been fast enough in the scenarios where I've used it. I was more puzzled about the lack of symmetry.

    As a matter of curiosity, why is an AutoResetEvent hard to write? I guess to be technically correct in its behaviour you'd need to implement a queue for the waiters, because relying on Monitor.Wait's intrinsic queuing might be tricky - especially if you want to spin for a few cycles first. And you'd need to deal with timeouts and cancellation tokens. OK - maybe I've answered my own question!

    Joe

    Write LINQ queries interactively - www.linqpad.net