Сравнение ConcurrentQueue.Count с целым числом возвращает неверный результат - PullRequest
0 голосов
/ 22 апреля 2019

Я пишу обычную функцию чтения-записи с одним основным потоком, который уравнивает, и несколькими потоками, которые удаляют из очереди. Итак, есть часть кода, где я сравниваю количество элементов в моем 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();
                }
            }
        }
    }
}

В отчаянии я добавил ведение журнала и вижу, что во время модульного тестирования проблема воспроизводима даже внутри оператора блокировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...