Я пишу обычную функцию чтения-записи с одним основным потоком, который уравнивает, и несколькими потоками, которые удаляют из очереди. Итак, есть часть кода, где я сравниваю количество элементов в моем ConcurrentQueue
с некоторым целым числом, давайте назовем его «maxSize». Несмотря на то, что .Count
возвращает 1 и maxSize равно 10, queue.Count >= maxSize
возвращает true.
Я попытался отладить с помощью точек останова, установить только один поток удаления и даже приостановить его. Это произошло сразу после того, как основной поток был поставлен в очередь, и после нескольких строк кода это сравнение возвращает результат, который говорит: 1> = 10.
Я уверен, что основной поток помещает только 1 элемент в данный момент, я уверен, что Dequeue()
не был вызван. Кроме того, я попытался перепроверить с блокировкой, но иногда это не помогает.
Мне интересно, что может быть какая-то магия , которая не позволяет мне правильно сравнивать значения так, как я это делаю, потому что когда я вижу в отладчике, что 1> = 10 истинно, я разрываюсь друг от друга.
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();
}
}
}
}
}
В отчаянии я добавил ведение журнала и вижу, что во время модульного тестирования проблема воспроизводима даже внутри оператора блокировки.