Establecer tiempo de espera al realizar llamadas externas en un complemento
Categoría: rendimiento
Potencial de impacto: alto
Síntomas
Si un complemento realiza solicitudes web externas que no responden rápidamente, el complemento esperará el período de tiempo de espera predeterminado completo antes producir error. Esta duración puede producir una transacción larga que pueda afectar a otras operaciones. Si se registra el complemento:
Los usuarios pueden experimentar de forma sincrónica:
- Aplicaciones basadas en modelos que dejan de responder
- Interacciones lentas con el cliente
- El explorador deja de responder
De forma asincrónica, las ejecuciones de complementos pueden prolongarse durante más tiempo antes de dar error.
Instrucciones
El valor de tiempo de espera predeterminado para clientes .Net Htttp es de 100 segundos, solo 20 segundos menos que el tiempo disponible para que termine el complemento. Lo mejor es establecer un tiempo base esperado al que responderá un servicio de llamada. Cuanta más supere este tiempo de respuesta normal, mayor será la probabilidad de que finalmente produzca un error. Como práctica recomendada para rendimiento, es mejor que el error se produzca rápidamente que permitir que el período de tiempo de espera predeterminado expire. Deberá controlar el periodo que esperará la llamada al servicio externo.
El valor de tiempo de espera que debe establecer dependerá del servicio. Por ejemplo, si puede supervisar el rendimiento del servicio puede determinar una duración en la que 99,999% de las solicitudes tengan éxito y establecer el período de tiempo de espera con esa duración con un búfer de unos segundos. Esto evitará que los valores atípicos ocasionales tengan un impacto excesivo en el rendimiento del complemento.
Si usa la clase System.Net.Http.HttpClient, puede establecer el valor de Timeout
de forma explícita, como se indica en este ejemplo que establece el tiempo de espera en 15 segundos.
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false
HttpResponseMessage response = client.GetAsync(webAddress).GetAwaiter().GetResult(); //Make sure it is synchronous
response.EnsureSuccessStatusCode();
string responseText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //Make sure it is synchronous
tracingService.Trace(responseText);
//Log success in the Plugin Trace Log:
tracingService.Trace("HttpClientPlugin completed successfully.");
}
Si usa la clase System.Net.WebClient, necesita crear una clase derivada y reemplazar el método base GetWebRequest para establecer el tiempo de espera:
/// <summary>
/// A class derived from WebClient with 15 second timeout and KeepAlive disabled
/// </summary>
public class CustomWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
if (request != null)
{
request.Timeout = 15000; //15 Seconds
request.KeepAlive = false;
}
return request;
}
}
A continuación puede usar esta clase en el código del complemento:
using (CustomWebClient client = new CustomWebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
tracingService.Trace(response);
//Log success in the Plugin Trace Log:
tracingService.Trace("WebClientPlugin completed successfully.");
}
Vea también
Ejemplo: acceso web desde un complemento de espacio aislado
Establecer KeepAlive en false para interactuar con hosts externos en un complemento
Nota
¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)
La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).