admin管理员组文章数量:1606460
项目转战页游(?),需要在首包开始游戏后,背景下载后续的资源。这个模块是用httpwebrequest实现的,也考虑过webClient,据说webclient没法显示进度和错误码(主程说的,其实好像也是有的)。那就用httpwebrequest的。采用异步下载,例子参考至msdn,连接如下:https://msdn.microsoft/en-us/library/system.httpwebrequest.begingetresponse(v=vs.110).aspx
实际项目中未使用ManualResetEvent。实际测试结果会遇到问题,经常在endGetResponse吃,报错,捕获webexception,status=receiveFailture。google后,发现相关的解决方案比较少。反而msdn针对各种status有相关解决推荐。连接如下:https://docs.microsoft/en-us/dotnet/framework/network-programming/understanding-webrequest-problems-and-exceptions。
通过解决推荐,了解到默认http的默认连接数是2,首先这个http连接数本身很少,可以通过设置DefaultConnectionLimit将连接数调大点。往往,假设connection不正常的关闭,会导致connection不会被释放,从而导致连接数被占用。仔细查代码,发现了喜感的事:
private long GetLength(string url)
{
HttpWebRequest _request = WebRequest.Create(url) as HttpWebRequest;
_request.Method = "HEAD";
HttpWebResponse _response = _request.GetResponse() as HttpWebResponse;
long _ret = _response.ContentLength;
_response.Close();//这里是新加的,切记response必须要关闭。
return _ret;
}
这里用上述同步方法获得url对应的资源的大小,用于显示加载的进度。忘记关闭,就会导致connection被占用,释放不了。然后产生receive Failture。最后,在endResponse在获得资源的大小即可。综上,切记getResponse或者endGetResponse,同步、异步方法后都要记得调用response.close方法。
将默认连接数改大,同时修正上述时,发现不会在大批量的出现receive failture了。但是偶尔还会有资源下载失败的情况。这时候根据msdn推荐,进行了如下设置:
//创建一个初始化请求对象
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.KeepAlive = false;//这个有用
request.Proxy = WebRequest.DefaultWebProxy;//不使用代理,减少自动搜索代理的过程,提升性能
//设置下载相关参数
requestState.RetryTime = 4;//增加下载失败重试次数
requestState.StateObject = this;
同时,在捕获到一些status时,重新尝试下载几次。基本上就解决了资源下载不下来的问题。
private bool IsRetryable(WebException ex)
{
return
ex.Status == WebExceptionStatus.ReceiveFailure ||
ex.Status == WebExceptionStatus.ConnectFailure ||
ex.Status == WebExceptionStatus.KeepAliveFailure;
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.RequestCanceled)
return;
Debug.LogErrorFormat("\nRespCallback Exception raised!");
Debug.LogErrorFormat("\nMessage:{0}", e.Message);
Debug.LogErrorFormat("\nStatus:{0}", e.Status);
Debug.LogErrorFormat("请求资源响应失败,资源url{0}", m_RequestState.Url);
Connection.pool.log("ResponseCallback资源异常 WebException StackTrace :{0}, Message:{1}, Status:{2}, 资源url:{3}。", e.StackTrace, e.Message, e.Status, m_RequestState.Url);
if (IsRetryable(e))
{
TryRequest(requestState);
System.Threading.Thread.Sleep(2);//当前下载线程休息2ms
}
else
{
int _stateCode = 0;
if (requestState.Response != null)
_stateCode = (int)requestState.Response.StatusCode;
Connection.pool.log("下载资源异常Response Code :{0}, Message:{1}, 资源url:{2}。", _stateCode, e.Message, m_RequestState.Url);
m_IsSuccess = true;
requestState.StateObject.DownLoadCompleted();
return;
}
//m_IsSuccess = false;
//requestState.StateObject.DownLoadCompleted();
}
注:404错误要忽略哦。
参考:
http://wwwblogs/summer_adai/archive/2013/04/26/3045253.html
本文标签: 解决方案文件HttpWebRequest
版权声明:本文标题:httpwebrequest下载文件失败的解决方案 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728501519a1161228.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论