Доступ к SQL-серверу с помощью WCF: время ожидания - PullRequest
1 голос
/ 20 августа 2009

У меня есть сервер с базой данных SQL2008 и IIS7. Я создал службу WCF, которая обращается к SQL-серверу и возвращает набор результатов в виде List<T>.

Моя проблема в том, что я получаю тайм-ауты при доступе к сервису от моего клиента, хотя запрос не должен занимать слишком много времени (около 1 секунды в SQL-менеджере), он получает 17.256 строк.

Когда я ограничиваю запрос чтением десятка строк, он работает нормально:

SqlCommand command = new SqlCommand("SELECT stammDatenId, position, latitude, longitude FROM geoKoordinates ORDER BY stammDatenId, position", connection);
IDataReader reader = command.ExecuteReader();
int count = 0;

while (reader.Read())
{
    GeoKoordinates geoKoors = new GeoKoordinates();
    geoKoors.stammDatenId = reader.GetInt32(0);
    geoKoors.position = reader.GetInt32(1);
    geoKoors.latitude = reader.GetDouble(2);
    geoKoors.longitude = reader.GetDouble(3);

    resultSet.Add(geoKoors);
    if (count > 10)
        break;

    count++;
}
reader.Close();

Но, как вы можете догадаться, мне нужны все 17k строк. Скорость сетевого соединения не должна быть проблемой, поскольку сервер и мой клиент находятся внутри нашей локальной сети со 100-мегабитными линиями. При сохранении набора результатов в csv из SQL-Manager он составляет всего 600 КБ.

Есть идеи, где может быть узкое место и как это решить? Я понятия не имею, какая часть кода может иметь отношение к ответу на этот вопрос. Если вам нужно увидеть какие-то особенные детали, запишите это здесь, и я предоставлю это.

Ответы [ 5 ]

1 голос
/ 20 августа 2009

Вот одна маленькая вещь, которая может осложнить ваши результаты. Вы должны реализовать using блоков:

using (SqlCommand command = new SqlCommand(
   "SELECT stammDatenId, position, latitude, longitude "+
   "FROM geoKoordinates ORDER BY stammDatenId, position", connection))
{
    using (IDataReader reader = command.ExecuteReader())
    {
        // ...
    }
}
1 голос
/ 20 августа 2009

Какой таймаут?

Вы можете иметь:

  • Тайм-ауты SQL. Проверьте CommandTimeout на SqlConnection / DataContext
  • Тайм-ауты транзакций, установите TransacitonOptions.Timeout для ваших собственных TransactionScopes или установите следующую конфигурацию сервера WCF под соответствующим поведением
<serviceTimeouts transactionTimeout="00:10:00"/>
  • Или это тайм-аут WCF, это, вероятно, наиболее вероятно, поскольку вы будете конвертировать все данные в XML, и эти значения по умолчанию равны 1 минуте. Предположим, что receiveTimeout установлен на привязку на клиенте. Как заявляет marc_s, вы можете столкнуться с другими проблемами (но не с тайм-аутами) в зависимости от размера данных, и ниже приведены примеры этого тоже:

.

<wsHttpBinding>
  <binding name="PcsInterfaceSecureBinding" openTimeout="00:10:00" receiveTimeout="00:10:00"
   sendTimeout="00:10:00" maxBufferPoolSize="8000000" maxReceivedMessageSize="2147483647">
    <readerQuotas maxDepth="32" maxStringContentLength="65536000"
     maxArrayLength="2147483647" maxBytesPerRead="8192" maxNameTableCharCount="16384" />
    <security mode="Transport" />
  </binding>
</wsHttpBinding>
0 голосов
/ 20 августа 2009

Не возвращайте 17 000 строк. Пролистайте их. Это также позволит клиенту начать обработку, пока SQL делает свое дело и получает больше данных из БД.

0 голосов
/ 20 августа 2009

Вы можете столкнуться с проблемой не из-за тайм-аута, но из-за того, что размер сообщения WCF по умолчанию недостаточно велик.

По умолчанию WCF ограничен сообщениями 64 КБ - может быть, с 17 КБ строк, это уже слишком - звучит так, как вы пишете.

Вы можете увеличить размеры этих сообщений множеством настроек - большинство из них на вашей привязке. Это будет:

  • maxBufferPoolSize
  • MaxBufferSize
  • MaxReceivedMessageSize

Для настройки значений, например, wsHttpBinding, используйте этот фрагмент:

<bindings>
  <wsHttpBinding>
    <binding name="LargeWsHttp"
             maxBufferSize="512000"
             maxBufferPoolSize="512000"
             maxReceivedMessageSize="512000" />
  </wsHttpBinding>

А затем просто укажите ссылку на ваши конечные точки (как на стороне клиента, так и на стороне сервера!):

<endpoint address="......"
          binding="wsHttpBinding" 
          bindingConfiguration="LargeWsHttp" 
          contract="......" />

Другие настройки находятся на <ReaderQuotas> (в качестве подтэга в вашем связывании) - к ним относятся:

  • maxStringContentLength
  • MaxArrayLength
  • maxBytesPerRead
  • maxNameTableCharCount

Они - как следует из названия «читательские квоты», вероятно, более актуальны для сервера, когда он получает сообщения.

Марк

0 голосов
/ 20 августа 2009

Увеличение времени ожидания в файле конфигурации для привязки. Проверьте, если ошибка все еще происходит. Смотрите эту ссылку. Могу помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...