Как установка EF (6) Command Timeout взаимодействует с потоковым запросом
У меня есть приложение с несколькими сложными запросами, среди обычных операций CRUD.
Я просто исправлял проблему, когда куча вызовов кода меняла время ожидания контекста, а не сбрасывала его. В общем, я хочу оставить нормальный низкий тайм-аут после выполнения длинных запросов.
Для большинства больших запросов управление тайм-аутом довольно тривиально, так как я помещаю весь набор данных в память. Итак, я получаю:
- Установите длительное время ожидания
- Запустите запрос
- Завершить запрос
- Исправьте данные в памяти
- Установите время ожидания обратно к старому по умолчанию.
Simples! Писк.
Но в одном случае набор данных слишком велик, чтобы держать его в памяти за один раз, поэтому я активно использую тот факт, что EF предлагает потоковую передачу - лениво повторяя исходный IQueryable, передавая его как IEnumerable, обрабатывая каждый элемент по очереди, с звонками Linq или yield return
заявления.
Раньше это было хорошо, потому что я установил длинный тайм-аут, а затем никогда не сокращал его (и тайм-аут был огромным, поэтому он охватывал как выполнение запроса, так и всю обработку). Но теперь я хочу сбросить его.
Если бы я сделал это наивно, выполнение кода было бы таким:
- Установите длительное время ожидания
- Инициировать потоковый запрос
- Установите время ожидания обратно к старому по умолчанию.
- Прочитайте и используйте первую возвращенную запись.
- Прочитайте и используйте последнюю возвращенную запись.
- Потоковый запрос завершен.
т.е. запрос все еще выполняется после сброса времени ожидания.
Я не могу найти документацию о том, как CommandTimeouts взаимодействует с потоковыми запросами.
Кто-нибудь знает, как это работает?
Будет ли вышеуказанный метакод работать правильно или нет?
Является ли тайм-аут команды фиксированным для запроса в точке, в которой запрос инициирован, или выполняется каким-либо другим способом?
В этом отношении, я действительно не знаю деталей реализации потоковых запросов. SQL Server знает, что запрос должен быть передан в потоковом режиме, или как?
1 ответ
С момента, когда клиент отправляет запрос, до момента, когда он извлекает последнюю строку, на которой выполняется запрос на SQL Server. Результаты могут быть помещены в буфер, или TempDb, или план запроса может активно выполняться, когда клиент выбирает строки.
SqlCommand.CommandTimeout - это тайм-аут на стороне клиента, который измеряет (в случае запроса, возвращающего результаты), как долго клиент ожидает ответа на SqlCommand.ExecuteReader(), SqlDataReader.Read() и SqlDataReader.NextResult().
Является ли тайм-аут команды фиксированным для запроса в точке, в которой запрос инициирован, или выполняется каким-либо другим способом?
Это набор в SqlCommand, и когда вы изменяете тайм-аут в EF, это не должно влиять на выполнение запросов.