WCF перестает отвечать после примерно 10 вызовов (регулирование)
у меня есть служба WCF и приложение со ссылкой на нее, а с приложением у меня есть цикл, и на каждой итерации он вызывает метод в этой веб-службе wcf.
проблема в том, что после примерно 9 звонков или около того, он просто останавливается...и если вы нажмете Pause
кнопка VS, вы увидите, что он застрял на линии, где он делает вызов.
после некоторого времени ожидания этого, это TimeoutException is бросил:
запрос канала истекло время ожидание ответа после 00: 00: 59.9970000. Увеличить время ожидания значение, переданное вызову Request или увеличьте значение SendTimeout на Обязательный. Время, отведенное на это операция могла быть частью больше времени ожидания.
Я немного исследовал это и нашел некоторые решения, связанные с редактированием приложения.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
подключение...Теперь я закрываю соединение после каждого запроса, и он работает как шарм.
хотя то, что я до сих пор не могу понять, это в моем приложении.config, я установил свои maxConcurrentCalls и maxConcurrentSessions на 500, и все же я могу сделать только 10. У кого-нибудь есть ответ на этот вопрос? (возможно, у меня что-то не так в моем приложении.конфиг выложил выше)
ответ на вышеуказанный вопрос (теперь пунктирный) заключается в том, что я редактировал клиент app.config
, а не файл конфигурации службы (web.config
)
6 ответов
по умолчанию количество одновременных подключений 10.
Скорее всего ваш клиент не закрывает соединение.
чтобы увеличить количество одновременных вызовов, вам придется добавить свое поведение в конфигурацию службы, а не клиента.
я столкнулся с этой проблемой на этой неделе и я не мог понять, что происходит.
Я на самом деле изменил свой звонок на мой сервис на Dispose()
клиент службы, но это, похоже, не имело никакого эффекта. Очевидно, где-то скрывался еще один звонок.
что может быть интересно отметить, это то, что заставило меня решить, что это было не проблема: это ограничение не связано с фактическим количеством подключений сокетов к веб-сервису. Когда вы хит maxConcurrentSessions
предел, есть еще только один разъем подключения. Я проверял это с помощью netstat
, что привело меня к неправильному выводу. Итак,не путайте сеансы с сокетами.
у нас есть интерфейсы, определенные для всех наших служб WCF, поэтому я планирую адаптировать этот шаблон в своем коде сейчас:
IMyService service = new MyServiceClient();
using (service as IDisposable)
{
service.MyServiceMethod();
}
что также интересно, так это то, что проблема не возникла для меня, когда службы (и веб-сайт) были размещены на сервер IIS. Конфигурация (почти) идентична, но я не мог воспроизвести это поведение на этой машине. Думаю, это хорошо:)
@ John Saunders (о назначении переменных в using
):
я обычно помещаю назначение переменной в using
заявление. Но генерируемый IMyService не является неявно конвертируемым в IDisposable
. Если бы вы действительно хотели, чтобы задание было там, я полагаю, альтернативой было бы:
IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}
что еще однако оставляет проблему переменной области видимости неправильной. Ссылка на IService service
непригодно, но все еще в области. Так что это было бы лучше в этом отношении:
using (IDisposable serviceDisposable = new ServiceClient())
{
IService service = (IService)serviceDisposable;
}
это требует от меня ввести дополнительное имя переменной. * Meh*
Это можно решить, создав одноэлементный класс в качестве интерфейса между ссылкой на веб-службу и приложением. Затем он создаст только один экземпляр ссылки на службу.
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();
}
}
вы можете настройки трассировки и запустить цикл? Возможно, что канал становится неисправным и вызывает тайм-аут клиента.
после того, как потянул мои волосы за много аналогичная проблема, которая не была решена ни Close()
или Dispose()
Я хотел бы добавить простое решение, которое сделало мой день, а именно за счет увеличения ServicePointManager.DefaultConnectionLimit
что по умолчанию 2.
" свойство DefaultConnectionLimit задает максимальное число параллельных подключений по умолчанию, которое объект ServicePointManager назначает свойству ConnectionLimit при создании ServicePoint объекты."
в моем случае мое приложение успешно подключилось к моей удаленной службе 2 раза, с третьей попытки оно просто не пыталось подключиться к службе. Вместо этого он подождал некоторое время, прежде чем тайм-аут с тем же сообщением об ошибке, что и в вопросе выше. Увеличение DefaultConnectionLimit
разрешить это. Чтобы добавить к разочарованию, это поведение было несколько случайным - в одном случае из 10 веб-сервис был успешно вызван несколько (>2) раз.
решение берет начало и далее обсуждаются эти два потока:wcf-timeout-exception-detailed-investigation и wcf-service-дросселирование. решил мою проблему.