consumir c# wcf web-services throttling

consumir web service svc c#



WCF deja de responder despuĆ©s de aproximadamente 10 llamadas(aceleraciĆ³n) (6)

Tengo un servicio WCF y una aplicación con una referencia de servicio, y con la aplicación tengo un bucle y en cada iteración se realiza una llamada a un método en este servicio web wcf.

El problema es que después de aproximadamente 9 llamadas más o menos, simplemente se detiene ... y si presiona el botón Pause de VS, verá que está bloqueado en la línea donde realiza la llamada.

Después de un tiempo esperándolo, se lanza esta TimeoutException :

El canal de solicitud agotó el tiempo de espera mientras esperaba una respuesta después de 00: 00: 59.9970000. Aumente el valor de tiempo de espera pasado a la llamada para Solicitar o aumente el valor de SendTimeout en el Enlace. El tiempo asignado a esta operación puede haber sido una porción de un tiempo de espera más largo.

Investigué un poco sobre esto y encontré algunas soluciones que implicaban editar la aplicación.config en la aplicación, y aquí hay extractos de ella:

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

.

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

Luego, después de detener la depuración, después de un par de minutos, aparece un mensaje de error que indica que se ha producido una falla catastrófica .

¿Como puedo solucionar este problema? No tuve este problema cuando estaba trabajando con un servicio web normal.

Como referencia, aquí está toda la 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>

[Actualización] Solución:

Aparentemente, después de cada solicitud debes Close la conexión ... Ahora estoy cerrando la conexión después de cada solicitud y funciona como un amuleto.

Aunque lo que todavía no puedo entender es que en mi app.config, establezco mis maxConcurrentCalls y maxConcurrentSessions en 500, y aún así, solo puedo hacer 10. ¿Alguien tiene alguna respuesta para eso? (tal vez tengo algo mal en mi app.config publicado anteriormente)

La respuesta a la pregunta anterior (ahora discontinua) se debe a que estaba editando el cliente app.config , no el archivo de configuración del servicio ( web.config )


¿Puedes configurar el rastreo y ejecutar el ciclo? Es posible que el canal tenga una falla y cause que el cliente agote el tiempo de espera.


Después de poner mi pelos de punta en un problema muy similar que no fue resuelto por Close() o Dispose() me gustaría agregar una solución simple que hizo mi día, es decir, al aumentar el ServicePointManager.DefaultConnectionLimit que es por defecto 2.

"La propiedad DefaultConnectionLimit establece el número máximo predeterminado de conexiones simultáneas que asigna el objeto ServicePointManager a la propiedad ConnectionLimit al crear objetos de ServicePoint".

En mi caso, mi aplicación se conectó con éxito a mi servicio remoto 2 veces, en el tercer intento simplemente no intentó conectarse al servicio. En cambio, esperó un tiempo antes de agotar el tiempo con el mismo mensaje de error que en la pregunta anterior. El aumento de DefaultConnectionLimit resolvió esto. Para aumentar la frustración, este comportamiento fue algo aleatorio: en un caso de 10, el servicio web se invocó con éxito varias veces (> 2).

La solución se origina y se analizan con mayor profundidad estos dos hilos: wcf-timeout-exception-detailed-investigation y wcf-service-throttling . Resolvió mi problema.


El número predeterminado de conexiones simultáneas permitidas es 10.
Lo más probable es que su cliente no esté cerrando las conexiones.

Para aumentar el número de llamadas simultáneas, deberá agregar su comportamiento a la configuración del servicio, no al cliente.


Esto puede resolverse creando una clase singleton como interfaz entre la referencia del servicio web y la aplicación. Luego creará solo una instancia de referencia de servicio.

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(); } }


Me encontré con este problema esta semana y no pude entender qué estaba pasando. De hecho, cambié mi llamada a mi servicio para Dispose() el cliente de servicio, pero no pareció tener ningún efecto. Aparentemente, había otra llamada de servicio al acecho en algún lado.

Lo que puede ser interesante observar es lo que me hizo decidir que este no era el problema: este límite no está relacionado con el número real de conexiones de socket al servicio web. Cuando maxConcurrentSessions límite de maxConcurrentSessions , todavía hay una sola conexión de socket real . Estaba comprobando esto con netstat , lo que me llevó a la conclusión equivocada. Por lo tanto, no confundas las sesiones con sockets .

Tenemos interfaces definidas para todos nuestros servicios de WCF, así que estoy planeando adaptar este patrón en mi código ahora:

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

Lo que también es interesante, es que el problema no me ocurrió cuando los servicios (y el sitio web) estaban alojados en IIS. La configuración es (casi) idéntica, pero no pude reproducir este comportamiento en esa máquina. Creo que eso es algo bueno :)

@ John Saunders (sobre la asignación de variables en el using ):

Normalmente pongo la asignación de variable en la instrucción de using . Pero el servicio IMy que se genera no es implícitamente convertible a IDisposable . Si realmente deseabas la tarea allí, supongo que la alternativa sería:

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

Sin embargo, eso deja el problema de que el alcance de la variable está equivocado. La referencia al IService service se puede usar, pero aún está dentro del alcance. Entonces esto sería mejor a ese respecto:

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

Sin embargo, eso requiere que presente un nombre de variable adicional. * Meh *


Una llamada a clientservice.close () resolverá el problema.