Простые вызовы WCF занимают много времени

Я создаю клиент-серверное приложение WCF. Однако в моем первом тесте простой вызов (метод в основном просто return true;) занимает много времени (~ 5 секунд).

Я попытался отследить его, и вот скриншот трассировки вызова введите здесь описание изображения

Как вы можете видеть, между строками 2 и 3 есть промежуток в 5 секунд (хотя, если честно, я не знаю, что означают строки 2 и 3)

В конфигурации клиента (вызывающего) привязка такая (в основном генерируется Visual Studio

    <wsHttpBinding>
        <binding name="WSHttpBinding_IAgent" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="None">
          </security>
        </binding>
      </wsHttpBinding>

и на сервере

<wsHttpBinding>
    <binding name="WSHttpBinding_IAgent" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:05:00" sendTimeout="00:05:00"
      bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
      maxBufferPoolSize="16777216" maxReceivedMessageSize="16777216"
      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
      allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="16777216"
        maxArrayLength="16384" maxBytesPerRead="16384" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
        enabled="false" />
      <security mode="None"/>
    </binding>

И то, как я называю это примерно так

var client = new AgentClient(binding, BuildEndpointAddress(hostName, port));
for(int i =0; i<10; i++)
    client.IsAlive(); //this call is very slow despite just returning true;
    // subsequent calls are also slow so probably not because of wake-up time

Обратите внимание, что для этого теста и сервер, и клиент находятся на одном компьютере, поэтому проблема не может быть в сети. Любая идея, что вызывает медлительность или как я могу найти дополнительную информацию для устранения этой проблемы?


person Louis Rhys    schedule 04.06.2012    source источник
comment
Это быстрее при последующих вызовах? Может компилировать или просыпаться по первому звонку.   -  person McGarnagle    schedule 04.06.2012
comment
нет, я несколько раз пытался зациклить вызов client.IsAlive(), и последующие вызовы не отличаются от первого.   -  person Louis Rhys    schedule 04.06.2012
comment
@dbaseman Если быть точным, продолжительность действительно варьируется, но, похоже, это происходит из-за случайности, а не из-за систематики. Например, в моем первом тесте продолжительность последовательных вызовов (тот же метод) составляла 4 секунды, 4, 6, 2, 4, 3, 8, а когда я повторял попытку, это было: 9, 3, 2, 4, 5, 5 , 3   -  person Louis Rhys    schedule 04.06.2012
comment
Вы пробовали этот тест НЕ на том же компьютере? Вот ссылка на статью, в которой говорится о 5-секундной задержке при работе на локальном хосте: support.microsoft.com/ kb/2020447 К сожалению, в сценарии упоминается большой объем данных (> 64 КБ).   -  person Richard Morgan    schedule 04.06.2012
comment
@RichardMorgan Я только что попробовал, и использование другого компьютера тоже не улучшило его. Также не было изменено имя хоста на IP-адрес   -  person Louis Rhys    schedule 04.06.2012
comment
Если вам нужно посмотреть сетевой трафик, отлично подойдет fiddler2: fiddler2.com/fiddler2   -  person Morten Frederiksen    schedule 18.06.2012


Ответы (3)


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

В этом случае время имеет смысл.

.NET выполняет много скрытой работы по инициализации ChannelFactory и Server, если он не был прогрет, несмотря на использование облегченной привязки и сообщения.

Такова природа WCF, и она не должна вызывать особых проблем, потому что после прогрева обмен данными происходит очень быстро.

Попробуйте вызвать службу два раза подряд в одном сеансе приложения, замерив время для обоих вызовов. Если оба вызова занимают сопоставимое время, мое предположение неверно.

Если вы хотите увидеть мой вопрос и сравнить среду -

Почему первый вызов клиента WCF медленный?

person Dmitry Harnitski    schedule 05.06.2012

Чтобы получить дополнительную информацию, вы можете использовать трассировку событий для Windows (ETW) с монитором производительности. инструмент с сайта codeplex команды BCL. Одной из многих особенностей этого инструмента является то, что он может производить выборку указателя инструкций каждую миллисекунду и предоставлять управляемый стек вызовов для каждой выборки. Это может дать вам представление о том, что делает код в эти промежутки времени.

пс. Вот еще одна ссылка на статьи, в которых используется этот инструмент: http://naveensrinivasan.com/category/net/etw-net/

person Marc Sherman    schedule 04.06.2012

Попробуйте настроить ведение журнала трассировки WCF — подробности здесь: http://msdn.microsoft.com/en-us/library/ms733025.aspx

У меня были всевозможные проблемы с выдергиванием волос с WCF, но такого рода проблемы с производительностью на одном и том же компьютере я никогда раньше не видел. Как уже говорили другие, наиболее вероятной причиной будет «прогрев» сервера, но если вы звоните ему несколько раз, это не должно быть проблемой. Пробовали ли вы вызывать код несколько раз из своего клиентского приложения?

person Matt Roberts    schedule 18.06.2012