Это, похоже, относится к ошибке , которую я зарегистрировал (которая была отклонена). Вы можете увидеть источник этого здесь , и из того, что я прочитал, логика c в вашем (и моем) случае работает следующим образом:
- Запрошенный элемент добавления.
- Размер был бы превышен, если бы элемент должен был быть добавлен (
UpdateCacheSizeExceedsCapacity()
), поэтому отклоните запрос (молча, что я и возражал). - Кроме того, поскольку это условие было обнаружено, нажмите off
OvercapacityCompaction()
, который удалит ваш элемент.
Похоже, что существует состояние гонки, поскольку работа по уплотнению ставится в очередь в фоновом потоке; возможно, иногда ваш тест находит элемент, который все еще там?
Чтобы ответить на заданный вами c вопрос - нет, сначала он не добавляется, а затем удаляется избыток.
Редактировать:
Второй Get()
всегда возвращает ноль ... Я пропустил некоторую дополнительную обработку существующей записи, если найдена (хотя это не улучшает результат). Прежде чем проверять, будет ли размер превышен путем добавления элемента, есть следующее:
if (_entries.TryGetValue(entry.Key, out CacheEntry priorEntry))
{
priorEntry.SetExpired(EvictionReason.Replaced);
}
Т.е., если он находит вашу существующую запись, он помечает ее как выселенную. Затем он применяет тест UpdateCacheSizeExceedsCapacity()
, не считая того, что он просто выселил существующую запись (что, возможно, и могло бы).
Позже, все еще в Set()
/ SetEntry()
, в превышающей емкости case, он делает это:
if (priorEntry != null)
{
RemoveEntry(priorEntry);
}
..., что немедленно удаляет предыдущую запись. Так что, если и когда OvercapacityCompaction()
(или ScanForExpiredItems()
) получит это, не имеет значения, он уйдет до возвращения из Set()
/ SetEntry()
.
(я также обновил источник ссылка выше на текущее значение; не меняет логи c).