Исключение таймаута после асинхронных команд и Task.WhenAny ждет в StackExchange.Redis

Я испытываю так называемый Timeout, выполняющий HGET-компанию: продукт: настройки, inst: 1, queue: 8, qu = 0, qs = 8, qc = 0, wr = 0/0, in = 79/1 исключение тайм-аута.

Странно, потому что тот же экземпляр Redis и на том же компьютере хранит данные, но это конкретное приложение, которое выдает это исключение. Обновление: на самом деле одно и то же приложение, на одну строку выше, получает данные от Redis. Проблема заключается в HGET.

Кроме того, я увеличил тайм-ауты в конфигурации мультиплексора до 6 секунд без везения.

Кроме того, я проверил, что экземпляр IDatabase имеет IsConnected с true значением.

Как интерпретировать эти сообщения об ошибках и что проблема за весь таймаут?

Некоторые фон...

Я успешно исправил проблему, когда какой-то раздел кода получает базу данных (т.е. multiplexer.GetDatabase()).

В то время как мультиплексор имеет экземпляр на AppDomain, как описано в документации StackExchange.Redis, многие инверсии компонентов управления создают в своем коде несколько экземпляров IDatabase. То есть экземпляр IDatabase не используется.

Фактический код выполняет ListRightPopLeftPush, а затем создает экземпляр инверсии управляющего компонента, который считывает хэш-ключ во время компонентного статирования. Если экземпляр всего компонента перед выполнением так называемого ListRightPopLeftPush, тогда весь HashGet не будет вызывать исключение таймаута.

Похоже, что даже когда ListRightPopLeftPush выполняется из другого экземпляра IDatabase, он производит некоторую проблему в следующем экземпляре IDatabase, когда дело доходит до выполнения операций чтения.

Во всяком случае, мое исправление не отвечает на вопрос. Я только что добавил более подробную информацию, чтобы найти, что проблема и ее собственное решение.

Update

В любом случае вышеупомянутое "исправление" не будет исправлять дальнейшие обращения к чтению в Redis. Я получаю такое же исключение тайм-аута в последующих вызовах. И теперь in paramater, найденный в сообщении об исключении, говорит 60/1.

Ответ 1

Основываясь на длительной дискуссии в чате и много копании, похоже, что в некоторых неясных сценариях TPL захватывает выделенный поток читателей, когда мы делаем такие вещи, как .TrySetResult (что: мы часто). Это вызывает мгновенный тупик, если вы выполняете синхронный вызов, так как он не может обрабатывать данные сокетов, если он занят, ожидая завершения задачи (которая будет выполняться только сама по себе). Фактически у нас есть код, чтобы предотвратить это, но похоже, что обходной путь фактически заставляет его произойти в некоторых других сценариях. Который... ужасен. Я посмотрю, что я могу найти. Но в основном проблема заключается в том, что в настоящее время в некоторых ограниченных сценариях TaskCompletionSource.TrySetResult дает возможность TPL запускать синхронные продолжения. Это включает Task.WhenAny.