繁体   English   中英

C#GetResponse没有回来

[英]C# GetResponse not coming back

我有一个奇怪的问题。 我的.NET DataController将响应发送到Java服务器(REST)。 一切正常,但是当我经常发送响应时,突然没有返回的GetResponse方法挂起。 我不知道是什么问题。

这是我的代码

ServicePointManager.DefaultConnectionLimit = 20;

public string HttpGet(string url, string requestAccept)
{
  if(string.IsNullOrEmpty(url))
    throw new Exception("HttpGet: no REST service URL provided");
  if(string.IsNullOrEmpty(requestAccept))
    requestAccept = defaultRequestAccept;

  if(!url.Equals("pc/alive"))
  {
    if(string.IsNullOrEmpty(SessionId))
    {
      if(string.IsNullOrEmpty(Authorization()))
        throw new WebException("HttpGet: no login");
    }
  }

  int tries = RestAccessData.MaxReconnect;
  string result = string.Empty;

  do
  {
    try
    {
      var request = NewWebRequest(url, "GET", false, true, requestAccept);

      using(var response = request.GetResponse() as HttpWebResponse)
      {
        UpdateSessionId(response);

        HttpStatusCode statusCode = response.StatusCode;
        LOG.Debug("...StatusCode: {0} ({1})", (int) response.StatusCode, response.StatusDescription);

        if((int) response.StatusCode < 500)
          lastContactWithServer = DateTime.Now.Ticks;

        switch(statusCode)
        {
        // Informational 1xx
        case HttpStatusCode.Continue: // 100
        case HttpStatusCode.SwitchingProtocols: // 101

          throw new HttpResponseException(response);

        // Successful 2xx
        case HttpStatusCode.OK: // 200

          result = ReadContent(response);
          response.Close();

          return (result);

        case HttpStatusCode.NoContent: // 204 The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation.

          response.Close();
          return (string.Empty);

        case HttpStatusCode.Created: // 201
        case HttpStatusCode.NonAuthoritativeInformation: // 203

          result = ReadContent(response);
          throw new HttpResponseException(response, result);

        case HttpStatusCode.Accepted: // 202 The request has been accepted for processing, but the processing has not been completed.
        case HttpStatusCode.ResetContent: // 205 The server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent.
        case HttpStatusCode.PartialContent: // 206 The server has fulfilled the partial GET request for the resource.

          throw new HttpResponseException(response);

        case HttpStatusCode.Unauthorized:

          throw new HttpResponseException(response);

        default:

          throw new HttpResponseException(response);
        }
      }
    }
    catch(WebException ex)
    {
      HandleWebException(ex);
    }
    catch(HttpResponseException ex)
    {
      throw ex;
    }
    catch(SystemException ex)
    {
      LOG.Error(ex, "caused a(n) {0}", ex.GetType().Name);
    }
    catch(Exception ex)
    {
      LOG.Warn(ex, "HttpGet: An error occured while trying to contact the server. Reason: {0}", ex.Message);
      throw new UserException("An error occured while trying to contact the server.", ex);
    }
  }
  while(0 < tries--);

  return (string.Empty);
}

private HttpWebRequest NewWebRequest(string urlAsString, string requestType, bool withContentType, bool applicationJson, string requestAccept)
{
  urlAsString = string.Format("{0}{1}", RestAccessData.GetUrl(), EncodeUrl(urlAsString));
  Uri url;

  if(!Uri.TryCreate(urlAsString, UriKind.Absolute, out url))
    throw new NotSupportedException("url is not compatible");

  LOG.Info("RESTUrl {0}", urlAsString);

  try
  {
    var request = HttpWebRequest.Create(url) as HttpWebRequest;

    if(!string.IsNullOrEmpty(SessionId))
    {
      CookieContainer cookies = new CookieContainer();
      Cookie cookie = new Cookie
      {
        Name = "JSESSIONID",
        Value = SessionId,
        Domain = url.Host
      };

      cookies.Add(cookie);
      request.CookieContainer = cookies;
    }

    request.Timeout = RestAccessData.Timeout;
    request.Method = requestType;
    request.AllowAutoRedirect = true;
    request.AllowWriteStreamBuffering = true;
    request.KeepAlive = false;
    request.ContentLength = 0;
    request.Headers["Accept-Charset"] = "utf-8";
    request.Accept = requestAccept;
    request.UserAgent = LvsClient;

    if(withContentType)
      request.ContentType = applicationJson ? defaultApplicationJson : defaultApplicationWwwForm;

    if(!string.IsNullOrEmpty(credential.UserName) && !string.IsNullOrEmpty(credential.Password))
      request.Headers["Authorization"] = string.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credential.UserName, credential.Password))));

    return (request);
  }
  catch(Exception ex)
  {
    throw new UserException(TH.Translate("NewWebRequest caused an error"), ex);
  }
}

任何想法在哪里的问题?

这行让我不舒服:

using(var response = request.GetResponse() as HttpWebResponse)

如果响应不是HttpWebResponse那么它永远不会被设置-在as运营商会给你`空。

我找到了解决方案。 MSDN上有关理解MaxServicePointIdleTime和DefaultConnectionLimit的文章非常有用。 在我使用MaxServicePointIdleTime属性并阅读此注释之后

随时更改连接限制

我发现连接处于活动状态和连接关闭之间达到了很好的平衡。 使用MaxServicePointIdleTime和DefaultConnectionLimit后,我的客户端可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM