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.