У меня есть веб-приложение, которое получает данные от внешних сервисов. Сам запрос происходит так же, как в приведенном ниже коде — насколько я понимаю, довольно просто. Создайте запрос, запустите его асинхронно и позвольте обратному вызову обработать ответ. Отлично работает в моей среде разработки.
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);
}
}
Однако внешние тестовые среды и производственная среда по не зависящим от меня причинам могут не достичь целевого URL-адреса. Ладно, подумал я, тайм-аут запроса никому не повредит. Однако казалось, что каждый раз, когда время ожидания этого запроса истекало, ASP.NET аварийно завершал работу и IIS перезапускался. Журнал событий показывает мне, среди прочего, вот такую трассировку стека:
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)
...так что все сводится к SocketException, как мне кажется. И сразу после этого (в течение той же секунды) регистрируется другое событие (которое, как я предполагаю, имеет значение):
Exception Info: System.AggregateException
Stack:
at System.Threading.Tasks.TaskExceptionHolder.Finalize()
веб-запросы вызывают сбой IIS, что кажется очень странным. Я повторно реализовал MakeRequest
для синхронного выполнения запросов, что отлично работает. Время ожидания запроса в этих средах все еще истекает, но никакого ущерба не наносится, и приложение продолжает счастливо работать вечно.
Итак, я вроде как решил свою проблему, но почему это происходит? Кто-нибудь может просветить меня? :-)