[英]Why i'm getting time out exception and how should i handle this when using httpwebrequest to download a file?
这是代码:
HttpWebRequest request;
int currentIndex = 0;
void fileDownloadRadar(string uri, string fileName)
{
if (splash != null)
{
if (!splash.IsDisposed)
splash.UpdateProgressBar(0);
}
/*_request = WebRequest.Create(uri) as HttpWebRequest;
_request.CookieContainer = new CookieContainer();
_request.AllowAutoRedirect = true;
_responseAsyncResult = _request.BeginGetResponse(ResponseCallback, null);*/
request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
request.CookieContainer = new CookieContainer();
request.AllowAutoRedirect = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
long contentLength = response.ContentLength;
if (response.ContentType == "")
{
Logger.Write("ContentType is Empty download was not fine !!!!!");
}
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect) &&
response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
{
Logger.Write("ContentType is not empty meaning download is fine");
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(fileName))
{
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
currentIndex += bytesRead;
double percentage = (double)currentIndex / contentLength;
if (splash != null)
{
if (!splash.IsDisposed)
splash.UpdateProgressBar((int)(percentage * 100));
}
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
if (splash != null)
{
if (!splash.IsDisposed)
{
splash.UpdateProgressBar(100);
}
}
}
}
else
{
timer1.Stop();
timer3.Start();
}
if (splash == null)
FinishWebRequest();
}
唯一的例外是:
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
例外是:WebException
操作已超时
我看到发生异常时,变量bytesRead的值为1360,缓冲区的值为4096
System.Net.WebException occurred
HResult=-2146233079
Message=The operation has timed out.
Source=System
StackTrace:
at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at mws.Form1.fileDownloadRadar(String uri, String fileName) in d:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\Form1.cs:line 914
InnerException:
914行是:
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
也许我应该试着去捉住某个地方?
我的代码正在下载文件,然后当计时器计数5分钟后计时器开始运行,它再次下载同一文件,依此类推,每隔5分钟我不停地调用此方法来下载文件。
根据答案将其更改后,编辑这是我的代码:
HttpWebRequest request;
int currentIndex = 0;
void fileDownloadRadar(string uri, string fileName)
{
if (splash != null)
{
if (!splash.IsDisposed)
splash.UpdateProgressBar(0);
}
try
{
request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
request.Timeout = 10000;
request.CookieContainer = new CookieContainer();
request.AllowAutoRedirect = true;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
long contentLength = response.ContentLength;
if (response.ContentType == "")
{
Logger.Write("ContentType is Empty download was not fine !!!!!");
}
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect) &&
response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
{
Logger.Write("ContentType is not empty meaning download is fine");
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(fileName))
{
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
currentIndex += bytesRead;
double percentage = (double)currentIndex / contentLength;
if (splash != null)
{
if (!splash.IsDisposed)
splash.UpdateProgressBar((int)(percentage * 100));
}
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
if (splash != null)
{
if (!splash.IsDisposed)
{
splash.UpdateProgressBar(100);
}
}
}
}
else
{
timer1.Stop();
timer3.Start();
}
if (splash == null)
FinishWebRequest();
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
Logger.Write(ex.Status.ToString());
}
}
}
但是在大约一个小时左右可以正常工作并下载了几次文件之后,我又一次遇到了异常超时:
操作已超时
这次上线:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
和异常消息:
System.Net.WebException occurred
HResult=-2146233079
Message=The operation has timed out
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at mws.Form1.fileDownloadRadar(String uri, String fileName) in d:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\Form1.cs:line 899
InnerException:
我更改了响应,并使用了还添加了:request.Timeout = 10000; 并增加了尝试和捕捉。
您看到的超时是由ServicePointManager引起的-ServiceClassManager类管理ServicePoint对象的集合,该对象为HTTP连接提供连接管理。
简而言之,无论何时创建请求和响应,重要的是在响应对象上调用Close()
方法。 否则,它将阻止释放ServicePoint对象中的任何连接,因此,在某些时候,提出了关键数量的请求后,将无法再处理其他请求,并且您将经历超时。
有关更多详细信息,请查看本文: http : //blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx
HttpWebRequest req = CreateRequest();
HttpWebResponse res = req.GetResponse() as HttpWebResponse;
...
res.Close(); //you should always close the response
编辑:
正如@Kevin在评论中所说,另一种解决方案是将响应包装在using语句中,这将自动关闭连接:
using(HttpWebResponse res = req.GetResponse() as HttpWebResponse)
{
...
}
第一步是将代码放入try..catch中
try
{
//code
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
//log your exception
}
}
然后将Web响应包装在using块中,因为它会自动调用close并处理该对象
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
//your code
}
最后,我在您的代码中看到您尝试使用异步请求,也许您可以考虑一下,如果要处理大型文件以解决超时问题。 希望能帮助到你。
这可能适合您的问题,因为它被视为超时异常。 最有用的答案涉及:
https://msdn.microsoft.com/zh-CN/library/system.net.webrequest.timeout.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.