Как установка 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, это не должно влиять на выполнение запросов.

Другие вопросы по тегам