Puede que se quepa sin puertos disponibles al usar la propiedad ConnectionGroupName de la clase System.Net.HttpWebRequest del .NET Framework 2.0 o 4.0
Este artículo le ayuda a resolver el problema en el que puede que se quedo sin puertos disponibles al usar la propiedad de la clase en ConnectionGroupName System.Net.HttpWebRequest Microsoft .NET Framework 2.0 o 4.0.
Versión del producto original: Microsoft .NET Framework 2.0, 4.0
Número KB original: 2551125
Síntomas
Está usando la clase en la aplicación según el .NET Framework System.Net.HttpWebRequest 2.0 o 4.0. Al realizar la solicitud HTTP, se establece la propiedad de la clase en un nombre único ConnectionGroupName cada vez que se usa la clase.
Si constantemente sigue enviando solicitudes al servidor SAME con un valor único establecido en las solicitudes salientes cada vez y no permite que el objeto subyacente asociado a las solicitudes permanezca inactivo durante el tiempo de inactividad permitido, observará que el uso de puertos de la aplicación crece constantemente y nunca ConnectionGroupName System.Net.ServicePoint cae.
Esto hace que el objeto System.Net.ServicePoint subyacente asociado con el para crear único HttpWebRequest ConnectionGroup (s) y termina creando nuevo System.Net.Connection para cada uno de estos ConnectionGroup . Estos objetos subyacentes están asociados a una referencia de identificador de socket winsock única que permanece abierta en el proceso hasta que se da al objeto la oportunidad de permanecer inactivo durante un System.Net.Connection System.Net.ServicePoint período finito de tiempo. El valor predeterminado de esta hora es 100 segundos y se rige por la ServicePointManager.MaxServicePointIdleTime propiedad.
Si el objeto nunca se mantiene inactivo y si sigue creando nuevos (s) y, por lo tanto, un objeto subyacente, observará que la aplicación pronto se queda sin espacio de socket o números de puerto ServicePoint ConnectionGroup System.Net.Connection disponibles. El efecto inmediato de este problema es que la aplicación ya no podrá crear nuevos objetos y empezar a iniciar una excepción que indica que no se pudo realizar una operación en un socket porque el sistema carecía de suficiente espacio de búfer o porque una cola estaba llena, lo que corresponde al Connection error winsock 10055 = WSAENOBUFS.
Si captura un archivo de volcado de memoria del proceso durante este síntoma, verá muchos objetos, objetos y objetos presentes en el archivo de volcado que el recolector de elementos no utilizados no ha System.Net.Sockets.Socket System.Net.ConnectionGroup System.Net.Connection limpiado.
Por ejemplo:
0:000> !dumpheap -type System.Net.Sockets.Socket -stat
total Sock_Count objects
Statistics:
MT Count TotalSize Class Name
<<MT>> Sock_Count <<Size>> System.Net.Sockets.Socket
Total Sock_Count objects
0:000> !dumpheap -type System.Net.ConnectionGroup -stat
total Group_Count objects
Statistics:
MT Count TotalSize Class Name
<<MT>> Group_Count <<Size>> System.Net.ConnectionGroup
Total Group_Count objects
0:000> !dumpheap -type System.Net.Connection -stat
total Conn_Count objects
Statistics:
MT Count TotalSize Class Name
<<MT>> Conn_Count <<Size>> System.Net.Connection
Total Conn_Count objects
Donde Sock_Count, Group_Count y Conn_Count es el recuento de los objetos, los objetos y los objetos respectivamente y normalmente será un gran número en Socket ConnectionGroup Connection miles.
Causa
El uso constante del mismo objeto para crear (s) únicos nunca permite que el objeto permanezca inactivo, lo que hace que nunca tenga la oportunidad de limpiar los objetos subyacentes que han estado inactivos durante más del tiempo asignado ServicePoint ConnectionGroup ServicePoint ServicePoint System.Net.Connection (100 segundos predeterminado).
Cada uno o reserva un número de puerto local y, al alcanzar el límite del sistema (valor predeterminado Connection 5000), no podrá realizar conexiones Socket adicionales.
Solución
Si se está ejecutando este tipo de problema en el que se ven muchos objetos debido a la creación constante de una propiedad única de la clase, se recomienda limitar el número de System.Net.Connection ConnectionGroupName HttpWebRequest (s) a un número limitado para evitar que se quedándose sin puertos ConnectionGroup disponibles. Limitar el número de (s) garantizará que el número máximo de que se abren esté restringido y no aumente más allá de los ConnectionGroup Connections límites disponibles.
Otra alternativa para evitar que se ejecute en este escenario es deshabilitar el comportamiento Keep-Alive http de la clase HttpWebRequest estableciendo la KeepAlive propiedad en false. Deshabilitar el comportamiento de Keep-Alive http garantizará que la conexión subyacente se cierre una vez que se atiende una solicitud, lo que garantiza que la referencia de socket se libera inmediatamente. Esto, a su vez, limpiará la referencia y y no dependerá de que expire System.Net.Connection System.Net.Sockets.Socket su temporizador ServicePoint inactivo.
También puede llamar a la función periódicamente desde la aplicación que liberará cualquier referencia antigua System.Net.ServicePoint.CloseConnectionGroup Connection o Socket inmediatamente. Sin embargo, para usar esta función, hará lo siguiente:
Necesita recuperar el
ServicePointobjeto asociado con el nombre del servidor web actual.Una vez que recupere el objeto, llame a la función del objeto recuperado y pase los nombres de lo que haya creado hasta ahora en la aplicación y tenga que
ServicePointCloseConnectionGroupServicePointConnectionGroupNamelimpiarse.
Puede usar el siguiente código como ejemplo:
void CloseIdleConnectionGroups(String[] strGroups, String strURL)
{
try
{
System.Net.ServicePoint oSP = System.Net.ServicePointManager.FindServicePoint(new Uri(strURL));
foreach (String strGroup in strGroups)
{
oSP.CloseConnectionGroup(strGroup);
}
}
catch (Exception oEx)
{
// handle the exception
}
}