HttpWebRequest超时处理

26

我有一个非常简单的问题。我正在使用HTTP POST将文件上传到服务器。问题在于,当连接超时时,我需要特别处理,并在超时后添加一定的等待算法以缓解服务器的压力。

我的代码非常简单:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("SomeURI");
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.KeepAlive = true;
request.Accept = "*/*";
request.Timeout = 300000;
request.AllowWriteStreamBuffering = false;

try
{
      using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
      {
            WebHeaderCollection headers = response.Headers;    
            using (Stream Answer = response.GetResponseStream())
            {
                // Handle.
            }
      }
}
catch (WebException e)
{
    if (Timeout_exception)
    {
       //Handle timeout exception
    }
}

由于文件读取代码不是我们关心的问题,我省略了它。现在我需要确保一旦抛出 WebException 异常,我会筛选异常以查看它是否确实是超时异常。我考虑通过比较异常消息来判断,但我不确定这是否是正确的方法,因为该应用程序是商业应用程序,我担心消息在不同语言之间会有所变化。而且我应该寻找什么样的消息。

有什么建议吗?

2个回答

56

您可以查看WebException.StatusWebExceptionStatus枚举具有Timeout标志:

try
{
   using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
   {
      WebHeaderCollection headers = response.Headers;    
      using (Stream answer = response.GetResponseStream())
      {
          // Do stuff
      }
   }
}
catch (WebException e)
{
   if (e.Status == WebExceptionStatus.Timeout)
   {
      // Handle timeout exception
   }
   else throw;
}

使用C# 6的异常过滤器可以在这里派上用场:

try
{
    var request = WebRequest.Create("http://www.google.com");
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        WebHeaderCollection headers = response.Headers;
        using (Stream answer = response.GetResponseStream())
        {
            // Do stuff
        }
    }
}
catch (WebException e) when (e.Status == WebExceptionStatus.Timeout)
{
    // If we got here, it was a timeout exception.
}

0

Yuval的回答非常直接,但这是我的一个版本,我已经尝试过了,因为我曾经处于相同的情况,如果你想通过状态码来定位目标:

catch (WebException ex)
            {
                var hwr = (HttpWebResponse)ex.Response;
                if (hwr != null)
                {
                    var responseex = hwr.StatusCode;
                    int statcode = (int)responseex;
                    if (statcode == 404)
                    {
                        Utility.Instance.log(logPath, "The file might not be availble yet at the moment. Please try again later or contact your system administrator.", true);
                    }
                    if (statcode == 401)
                    {
                        Utility.Instance.log(logPath, "Username and Password do not match.", true);
                    }
                    if (statcode == 408)
                    {
                        Utility.Instance.log(logPath, "The operation has timed out", true);
                    }
                }
                else
                {
                    Utility.Instance.log(logPath, ex + ". Please contact your administrator.", true);//Or you can do a different thing here
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接