I am writing usual reader-writer functionality with one main thread that equeues and several threads that dequeues. So, there is a part of the code where I am comparing count of items in my ConcurrentQueue with some integer number, let's call it "maxSize". Despite the fact that .Count returns 1 and maxSize is 10, queue.Count >= maxSize returns true.
I tried to debug with breakpoints, set only one dequeue thread and even pause it. That happened right after main thread enqueued and after several lines of code this comparing returns the result that says 1 >= 10.
I am sure the main thread puts only 1 item at this moment, I am sure no Dequeue() was called. Also, I've tried to double-check with locking but sometimes it does not help.
I am wondering that there could be some magic that does not allow me to compare values properly in a way I do it, because when I see in a debugger that 1 >= 10 is true, I'm torn apart.
int maxSize = 10;
Timer timer;
ctor(int interval)
{
queue = new ConcurrentQueue<HttpSessionState>();
timer = new Timer(TimeSpan.FromSeconds(interval).TotalMilliseconds);
timer.Elapsed += (sender, args) => PulseIfAvailableForProcessing(true);
}
void Process()
{
queue.Enqueue(obj);
// interval here is huge, several minutes
timer.Start();
PulseIfAvailableForProcessing(false);
}
bool PulseIfAvailableForProcessing(bool isTimeout)
{
if (isTimeout)
{
...
}
else
{
// here 1 >= 10 gives true
if (queue.Count >= maxSize)
{
lock (_dataLock)
{
// here in debug queue.Count is still 1, however 1 >= 10 returns false
if (queue.Count >= maxSize)
{
Pulse();
}
}
}
}
}
In despair I've added logging and I see that during unit testing the issue is reproducible even inside of a lock statement.
queue.Count >= maxSizethen it's safe to say that the values can't be 1 and 10. There are either more items in the queue, ormaxSizehas changed. The former seems more likely. It would help if we could see more context. There must be more to it than what we can see. Can you post the relevant parts of the class?queue.Enqueue(obj);and the firstifstatement I am startingSystem.Timers.Timer, it's callback calls theifstatements I described. Nothing more. And I tried to put infinite timeout to it - didn't help. I've updated code a little bit in the question.queue.Count(very unlikely on .net framework, plausible if running on .net core since the ConcurrentQueue has been revamped recently), there's a bug in the JIT (very very unlikely). In all three cases, we can't do anything without a reprovar count = queue.Count; if (count >= maxSize) { ... }, this way, you can inspect what value was used for the comparison, and we can rule out the JIT bug