我有一个非常简单的问题。我正在使用 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,我就会过滤异常以查看它是否确实是超时异常。我想与异常消息进行比较,但我不确定这是否是正确的方法,因为有问题的应用程序是一个商业应用程序,我担心消息因不同语言而异。我应该寻找什么信息。
有什么建议吗?
看看WebException.Status
.WebExceptionStatus
枚举有一个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.
}
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
}
}