You're using the wrong synchronization mechanism. Rather than a MRE just use a Semaphore. The semaphore will then represent the number of items yet to be processed. You can set it to add one, or wait on it to reduce it by one. There is no if
, you always do every semaphore action and as a result there is no race condition.
That said, you can avoid the problem entirely. Rather than managing the synchronization primitives yourself you can just use a BlockingCollection
. Have the producer add items and the consumer consume them. The synchronization will all be taken care of for you by that class, and likely more efficiently than your implementation would be as well.