Tengo una aplicación web que obtiene datos de servicios externos. La solicitud en sí sucede como el siguiente código, bastante sencillo por lo que puedo ver. Cree una solicitud, desactívela de forma asíncrona y permita que la devolución de llamada maneje la respuesta. Funciona bien en mi entorno de desarrollo.Async webrequest veces fuera => Bloqueos IIS
public static void MakeRequest(Uri uri, Action<Stream> responseCallback)
{
WebRequest request = WebRequest.Create(uri);
request.Proxy = null;
request.Timeout = 8000;
try
{
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith(task =>
{
WebResponse response = task.Result;
Stream responseStream = response.GetResponseStream();
responseCallback(response.GetResponseStream());
responseStream.Close();
response.Close();
});
} catch (Exception ex)
{
_log.Error("MakeRequest to " + uri + " went wrong.", ex);
}
}
Sin embargo, los entornos de prueba externos y el entorno de producción podrían, por motivos ajenos a mí, no alcanzar la URL de destino. Bien, pensé, un tiempo de espera de solicitud no dañará a nadie. Sin embargo, parecía que cada vez que se agotaba el tiempo de espera de esta solicitud, ASP.NET se bloqueaba e IIS se reiniciaba. El registro de eventos me muestra, entre otras cosas, esto StackTrace:
StackTrace: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.get_Result()
at MyApp.AsyncWebClient.<>c__DisplayClass2.<MakeRequest>b__0(Task`1 task)
at System.Threading.Tasks.Task`1.<>c__DisplayClass17.<ContinueWith>b__16(Object obj)
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
InnerException: System.Net.WebException
Message: Unable to connect to the remote server
StackTrace: at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endMethod, TaskCompletionSource`1 tcs)
InnerException: System.Net.Sockets.SocketException
Message: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
StackTrace: at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
.so todo se reduce a un SocketException, me parece. Y justo después (en el mismo segundo) otro evento (que supongo que es relevante) ha iniciado la sesión:
Exception Info: System.AggregateException
Stack:
at System.Threading.Tasks.TaskExceptionHolder.Finalize()
Esto es algo más allá de mí como yo no soy maestro de código asíncrono y roscado, pero eso un tiempo de espera de una solicitud web hace que IIS se bloquee parece muy extraño. Reimplementé MakeRequest
para realizar las solicitudes sincrónicamente, lo que funciona muy bien. La solicitud todavía expira en esos entornos, pero no se produce ningún daño y la aplicación continúa funcionando felizmente para siempre.
Así que he resuelto el problema, pero ¿por qué sucede esto? ¿Alguien puede iluminarme? :-)
Ah, entonces la explicación es así de simple. Pareció hacer el truco de inmediato. ¡Muchas gracias! Ahora, cómo recuperar esas horas desperdiciadas ... –