Время ожидания односторонних обратных вызовов WCF истекло?

Как это возможно? Я думал, что звонки в одну сторону — это выстрел и забвение. Метод помечен как односторонний. Для режима параллелизма обратного вызова установлено значение Multiple, а для UseSychronizationContext класса обратного вызова установлено значение false. Отправляемые данные составляют не более 1 КБ, но каждый раз, когда я отправляю около 30-40 небольших сообщений одновременно, вызовы начинают блокироваться, и в конечном итоге некоторые из них истекают. Я проверил свои вызовы клиент-> сервер со скоростью около 16000/сек. Когда я пытаюсь перезвонить клиенту, я могу собрать только около 2 в секунду, и это при одностороннем вызове!

Моя конфигурация привязки для сервера выглядит так:

<system.serviceModel>
<bindings>
  <netNamedPipeBinding>
    <binding name="netNamedPipeBinding1" receiveTimeout="23:00:00" maxReceivedMessageSize="1048576" maxBufferPoolSize="1048576" maxConnections="500">
      <readerQuotas maxStringContentLength="99999999" maxArrayLength="9999999" maxBytesPerRead="999999"/>
      <security mode="None"/>
    </binding>
  </netNamedPipeBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="highThroughPut">
      <serviceThrottling maxConcurrentCalls="3000" maxConcurrentInstances="3000" maxConcurrentSessions="3000"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service name="OLII.Apps.Services.Data.DataServices.DataService" behaviorConfiguration="highThroughPut">
    <endpoint bindingConfiguration="netNamedPipeBinding1" address="net.pipe://localhost/DataListener" binding="netNamedPipeBinding" contract="OLLI.Apps.Services.ProxyClients.DataServerProxyClient.IDataListenerService"/>
   </service>
</services>
</system.serviceModel>

Мой контракт обратного вызова выглядит так:

   public interface IDataCallbackClient
    {
        [OperationContract(IsOneWay = true)]
        void GetData(string file, int id);
    }

Мой клиентский класс обратного вызова выглядит так:

   [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
    public class DataCallback : IDataCallbackClient
    {
public void GetData(string file, int id)
{
//If I put Thread.Sleep(5000);  When the server calls this method, the first few go through, and subsequent calls block.  If I do a return statement here, all the calls go through really fast on the server side.
//Does some processing with file and id.  It then goes back to server with data.
}
}

person Kayode Leonard    schedule 13.04.2011    source источник
comment
Возможно, дросселирование используется и для обратного вызова? Какую версию .NET Framework вы используете?   -  person Ladislav Mrnka    schedule 13.04.2011
comment
Я использую .net 4.0. Я заметил, что на первую партию одновременных вызовов уходит очень много времени, а иногда даже теряется соединение. Следующая партия одновременных вызовов идет быстро. Есть ли здесь проблема с компиляцией JIT? Как мне даже закодировать это? У меня установлен очень высокий уровень регулирования: ‹serviceBehaviors› ‹behavior name=highThroughPut› ‹serviceThrottling maxConcurrentCalls=3000 maxConcurrentInstances=3000 maxConcurrentSessions=3000/› ‹/behavior› ‹/serviceBehaviors›   -  person Kayode Leonard    schedule 13.04.2011
comment
Что еще более странно, так это то, что если мой метод обратного вызова просто возвращает, обратный вызов выполняется быстро. Однако, если я засыпаю в свой метод обратного вызова, обратный вызов на сервере зависает, как если бы он ждал клиента. Однако это односторонние вызовы, так почему сервер должен ждать возврата обратного вызова клиента?   -  person Kayode Leonard    schedule 14.04.2011
comment
Это звучит действительно странно. Можете ли вы опубликовать дополнительную информацию о ваших контрактах на обслуживание и обратный вызов, а также о привязке?   -  person Ladislav Mrnka    schedule 14.04.2011
comment
Можете ли вы измерить, сколько вызовов может обработать клиент, прежде чем другие вызовы будут заблокированы и ожидают? Это всегда одно и то же число?   -  person Ladislav Mrnka    schedule 14.04.2011


Ответы (1)


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

person Kayode Leonard    schedule 14.04.2011