Исключение тайм-аута после асинхронных команд и Task.WhenAny ожидает в StackExchange.Redis
Я испытываю так называемую HGET-компанию, выполняющую тайм - аут: продукт: настройки, inst: 1, очередь: 8, qu = 0, qs = 8, qc = 0, wr = 0/0, исключение тайм-аута = 79/1,
Это странно, потому что тот же экземпляр Redis и на той же машине хранит данные, но это специальное приложение, которое выдает это исключение. Обновление: на самом деле то же приложение, на одну строку выше, получает данные от Redis. Вопрос с HGET
,
Кроме того, я увеличил таймауты в конфигурации мультиплексора до 6 секунд, но не повезло.
Кроме того, я проверил это IDatabase
экземпляр имеет IsConnected
с true
значение.
Как интерпретировать эти сообщения об ошибках и в чем проблема за все время ожидания?
Некоторый фон...
Я успешно исправил изменение проблемы, когда какой-то раздел кода получает базу данных (т.е. multiplexer.GetDatabase()
).
В то время как мультиплексор имеет экземпляр в AppDomain
как описано в документации StackExchange.Redis, многие инверсии компонентов управления создают много экземпляров IDatabase
в своем собственном коде. То есть, IDatabase
Экземпляр не является общим.
Фактический код выполняет ListRightPopLeftPush
и после этого он создает инверсию управляющего компонента, который читает хеш-ключ во время установки компонента. Если создать экземпляр всего компонента, прежде чем делать так называемый ListRightPopLeftPush
тогда весь HashGet
не будет выбрасывать исключение тайм-аута.
Кажется, даже когда ListRightPopLeftPush
выполнен из других IDatabase
Например, это создает какую-то проблему в следующем IDatabase
случай, когда дело доходит до выполнения операций чтения.
Во всяком случае, мое исправление не отвечает на вопрос. Я только что добавил более подробную информацию, чтобы мы могли найти причину проблемы и найти собственное решение.
Обновить
В любом случае, вышеупомянутое "исправление" не исправит дальнейшие обращения к Redis. Я получаю такое же исключение тайм-аута в дальнейших звонках. И сейчас in
Параматер найден в сообщении исключения говорит 60/1
,
1 ответ
Основываясь на длительном обсуждении в чате и большом количестве копаний, похоже, что в некоторых непонятных сценариях TPL захватывает выделенный поток читателей, когда мы делаем такие вещи, как .TrySetResult
(который: мы делаем часто). Это приводит к мгновенной взаимоблокировке, если вы делаете синхронный вызов, поскольку он не может обработать данные сокета, если занят, ожидая завершения задачи (которая будет выполнена только сама по себе). На самом деле у нас действительно есть код, специально предназначенный для предотвращения этого, но похоже, что обходной путь фактически заставляет его произойти в некоторых других сценариях. Который... ужасен. Я посмотрю, что я могу найти. Но в основном проблема заключается в том, что в настоящее время, в некоторых ограниченных сценариях, TaskCompletionSource.TrySetResult
дает возможность TPL запускать синхронные продолжения. Это включает Task.WhenAny
,