隐藏

C# HttpWebRequest.GetRequestStream() 报操作超时问题

发布:2023/5/31 11:22:22作者:管理员 来源:本站 浏览次数:278

写了个Http请求函数,在循环函数中多次请求之后报错:操作超时


原代码


    /// <summary>

           /// 请求结束返回状态码

           /// </summary>

           /// <param name="url">请求地址</param>

           /// <param name="type">请求类型</param>

           /// <param name="jsonStr">请求报文 json格式</param>

           /// <param name="headerMap">请求头</param>

           /// <returns></returns>

           public static int doHttpResponeStatusCode(String url, HttpRequestType type, string jsonStr, Dictionary<String, String> headerMap)

           {

               int statusCode = 200;

               HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

               req.ServicePoint.Expect100Continue = false;

               req.Method = GetTypeName.GetRequestTypeName(type);

               req.ContentType = "application/json";

               req.Accept = "application/json";

               HttpWebResponse resp = null;

               //设置请求头

               if (headerMap != null)

               {

                   foreach (var item in headerMap.Keys)

                   {

                       req.Headers.Add(item, headerMap[item]);

                   }

               }

               try

               {

                   //ring jsonStr = JsonConvert.SerializeObject(map);

                   LogHelper.Debug(string.Format("请求Url{0},参数:{1}", url, jsonStr));

   

                   byte[] data = Encoding.UTF8.GetBytes(jsonStr);

                   req.ContentLength = data.Length;

                   using (Stream reqStream = req.GetRequestStream())

                   {

                       reqStream.Write(data, 0, data.Length);

                       reqStream.Close();

                   }

   

                   resp = (HttpWebResponse)req.GetResponse();

                   statusCode = (int)resp.StatusCode;

               }

               catch (Exception e)

               {

                   LogHelper.Error(string.Format("请求Url{0}报错:{1}", url, e.Message));

               }

               return statusCode;

           }


问题原因:


因为多线程请求数量超过最大连接数量,导致无法再次发送请求,服务一直等待超时


改进:


1,将请求连接设为请求完成断开keepalive=false


2,请求对象和响应对象使用完即销毁req.Abort();resp.Close();


3,将多线程请求数量加大System.Net.ServicePointManager.DefaultConnectionLimit = 50;


优化后代码:


    /// <summary>

           /// 请求结束返回状态码

           /// </summary>

           /// <param name="url">请求地址</param>

           /// <param name="type">请求类型</param>

           /// <param name="jsonStr">请求报文 json格式</param>

           /// <param name="headerMap">请求头</param>

           /// <returns></returns>

           public static int doHttpResponeStatusCode(String url, HttpRequestType type, string jsonStr, Dictionary<String, String> headerMap)

           {

               System.Net.ServicePointManager.DefaultConnectionLimit = 50;//最大支持并发数50

               int statusCode = 200;

               HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

               req.ServicePoint.Expect100Continue = false;

               req.Method = GetTypeName.GetRequestTypeName(type);

               req.ContentType = "application/json";

               req.Accept = "application/json";

               req.KeepAlive = false;

               HttpWebResponse resp = null;

               //设置请求头

               if (headerMap != null)

               {

                   foreach (var item in headerMap.Keys)

                   {

                       req.Headers.Add(item, headerMap[item]);

                   }

               }

               try

               {

                   //ring jsonStr = JsonConvert.SerializeObject(map);

                   LogHelper.Debug(string.Format("请求Url{0},参数:{1}", url, jsonStr));

   

                   byte[] data = Encoding.UTF8.GetBytes(jsonStr);

                   req.ContentLength = data.Length;

                   using (Stream reqStream = req.GetRequestStream())

                   {

                       reqStream.Write(data, 0, data.Length);

                       reqStream.Close();

                   }

   

                   resp = (HttpWebResponse)req.GetResponse();

                   statusCode = (int)resp.StatusCode;

               }

               catch (Exception e)

               {

                   LogHelper.Error(string.Format("请求Url{0}报错:{1}", url, e.Message));

               }

               finally

               {

                   if (req != null)

                   {

                       req.Abort();

                   }

                   if (resp != null)

                   {

                       resp.Close();

                   }

               }

               return statusCode;

           }


操作超时还有另一个原因:等待时间过长导致超时,这个时候你可以将Request.TimeOut时间调整,根据对方接口的相应时间作为依据