Combining Interlocked.Increment and Volatile.Write

Entirely speculative possibility follows. In reality, I’d say that without explicit benchmarking, it probably doesn’t matter, and we could simply lose the Volatile.Read test, or even just use a lock. If there was explicit benchmarking, I’d hope for a comment hinting (or linking) at that.

We can infer from the naming (_runDrainOnce) that we only expect this to succeed once, and if something is only going to succeed once, we really don’t need the success case to be super optimal – so: having a redundant test in that success path: not a huge problem. In contrast, let’s speculate that the failure scenario is called many many times, and so having it fail just doing an acquire-fenced read (without attempting to write) may be beneficial.

The Schedule code is invoked by everything – see OnCompleted, OnError, OnNext, etc – so presumably the intent is to just make sure that the scheduling gets started, as efficiently as possible – so it doesn’t touch Intelocked more than necessary (once successfully, and possibly a few times indicating failure, if there is high thread competition initially)

You didn’t explicitly ask, but the lock/Pulse is a common pattern for having an idle worker loop waiting on receiving work using Monitor; you need to wake it if it was likely idle, which is when the count was zero and is now non-zero (hence the Interlocked.Increment).

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top