Подтвердить что ты не робот

WCF перестает отвечать после примерно 10 или около того вызовов (дросселирование)

У меня есть служба WCF и приложение с Service Reference к нему, а с приложением у меня есть цикл и на каждой итерации он делает вызов метода в этом веб-сервисе wcf.

Проблема в том, что после примерно 9 звонков или просто она останавливается... и если вы нажмете кнопку Pause на VS, вы увидите, что она застряла в строке, где она совершает вызов.

После некоторого времени ожидания этого TimeoutException выдается:

В течение ожидая ответа после 00: 00: 59,9970000. Увеличение таймаута значение, переданное на вызов для запроса или увеличьте значение SendTimeout на Связывание. Время, отведенное для этого возможно, была частью более длинный тайм-аут.


Я немного поработал над этим и нашел некоторые решения, связанные с редактированием app.config в приложении, и вот выдержки из него:

<serviceBehaviors>
    <behavior name="ThrottlingIssue">
        <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
    </behavior>
</serviceBehaviors>

.

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
 maxArrayLength="2147483647" 
 maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 

Затем, после прекращения отладки, через пару минут появляется сообщение об ошибке, сообщающее мне, что произошел Катастрофический сбой.

Как я могу исправить эту проблему? У меня не было этой проблемы, когда я работал с обычной веб-службой.


Для справки, вот целая app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ThrottlingIssue">
                    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IDBInteractionGateway" 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="2147483647" maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:28918/DBInteractionGateway.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDBInteractionGateway"
                contract="DBInteraction.IDBInteractionGateway" name="WSHttpBinding_IDBInteractionGateway">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

[Обновить] Решение:

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

Хотя то, что я до сих пор не могу понять, это то, что в моем app.config я установил мои maxConcurrentCalls и maxConcurrentSessions на 500, и все же я могу сделать только 10. У кого-нибудь есть ответ на этот вопрос? (возможно, у меня что-то не так в моем app.config выше)

Ответ на указанный вопрос (теперь пунктирный) заключается в том, что я редактировал клиент app.config, а не файл конфигурации службы (web.config)

4b9b3361

Ответ 1

Число разрешенных одновременных подключений по умолчанию равно 10.
Скорее всего, ваш клиент не закрывает соединения.

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

Ответ 2

Вызов функции clientservice.close() позволит решить проблему.

Ответ 3

На этой неделе я столкнулся с этой проблемой, и мне не удалось понять, что происходит. Я действительно изменил свой вызов на мою службу Dispose() на клиентскую службу, но, похоже, это не повлияло. По-видимому, там был другой служебный вызов.

Что может быть интересно отметить, так это то, что заставило меня решить, что это не проблема: этот предел не связан с фактическим количеством подключений сокетов к веб-сервису. Когда вы нажимаете предел maxConcurrentSessions, все еще существует только одно фактическое соединение сокета. Я проверял это на netstat, что привело меня к неправильному выводу. Итак, не путать сеансы с сокетами.

У нас есть интерфейсы, определенные для всех наших сервисов WCF, поэтому я планирую сейчас адаптировать этот шаблон в своем коде:

IMyService service = new MyServiceClient();
using (service as IDisposable)
{
    service.MyServiceMethod();
}

Интересно также, что проблема не возникла для меня, когда службы (и веб-сайт) были размещены в IIS. Конфигурация (почти) идентична, но я не мог воспроизвести это поведение на этой машине. Я думаю, что это хорошо:)

@Джон Сондерс (о присвоении переменной в using):

Я обычно помещаю назначение переменной в оператор using. Но созданный IMyService неявно конвертируется в IDisposable. Если вы действительно хотели получить задание, я полагаю, что альтернативой было бы следующее:

IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}

Это все еще оставляет проблему с областью переменной. Ссылка на IService service непригодна для использования, но все же в области видимости. Поэтому в этом отношении было бы лучше:

using (IDisposable serviceDisposable = new ServiceClient())
{
     IService service = (IService)serviceDisposable;
}

Это требует от меня ввести дополнительное имя переменной. * Мех *

Ответ 4

Это можно решить, создав класс singleton как интерфейс между ссылкой веб-службы и приложением. Затем он создаст только один экземпляр ссылки на службу.

class ServiceInterface
{
     private static ServiceInterface  _instance;
     private ServiceClient _service = new ServiceClient ;
     private ServiceInterface()
     {
       //Prevent accessing default constructor
     }

     public static ServiceInterface GetInstance()
     {

     if(_instance == null)

     {

      _instance = new ServiceInterface();

    }

        return _instance;



 }


   // You can add your functions to access web service here

    Public int PerformTask()
    {
         return _service.PerformTask();
    }
}

Ответ 5

Можете ли вы настроить трассировку и запустить цикл? Возможно, канал становится ошибочным и заставляет клиента отключиться.

Ответ 6

После того, как я потянул за волосы по той же проблеме, которая не была решена с помощью Close() или Dispose(), я хотел бы добавить простое решение, которое сделало мой день, а именно, увеличив ServicePointManager.DefaultConnectionLimit, который по умолчанию 2.

"Свойство DefaultConnectionLimit устанавливает максимальное количество одновременных подключений по умолчанию, которое объект ServicePointManager присваивает свойству ConnectionLimit при создании объектов ServicePoint."

В моем случае мое приложение успешно подключилось к моему удаленному сервису 2 раза, с третьей попытки он просто не пытался подключиться к службе. Вместо этого он подождал некоторое время, прежде чем тайм-аут с тем же сообщением об ошибке, что и в вопросе выше. Увеличение DefaultConnectionLimit разрешило это. Чтобы добавить к разочарованию, это поведение было несколько случайным - в одном случае из 10 веб-служба была успешно использована несколько ( > 2) раз.

Решение возникает и далее обсуждается эти два потока: wcf-timeout-exception-detailed-investigation и wcf-service-throttling. решил мою проблему.