我有一个网络应用程序,从外部服务获取数据.请求本身就像下面的代码一样 – 就我所见,非常简单.创建一个请求,异步激活它并让回调处理响应.在我的开发环境中正常工作.
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()
这有点超出我的范围,因为我不是异步代码和线程的掌握,但是来自Web请求的超时导致IIS崩溃似乎非常奇怪.我重新实现了MakeRequest来同步执行请求,效果很好.该请求在这些环境中仍然超时,但没有造成任何损害,应用程序继续快乐地运行.
所以我有点解决了我的问题,但为什么会这样呢?任何人都可以开导我吗?