WebClient的超时问题及解决

转载于

Webclient在下载请求时无法设置请求超时时间和请求读写超时时间。WebClient在异步下载时遇到网络不通等问题时没有响应超时造成app挂起。

1.Webclient请求超时设置
      重写Webclient的GetWebRequest方法,为HttpWebRequest添加请求超时及读写超时

     

        protected override WebRequest GetWebRequest(Uri address)
       
{
            HttpWebRequest request
= (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout
= 1000 * Timeout;
            request.ReadWriteTimeout
= 1000 * Timeout;
           
return request;
        }

2.WebClient在异步下载

       创建计时器监视响应情况,过期则取消下载

     

    public class Calculagraph
   
{
       
///<summary>
       
/// 时间到事件
       
/// </summary>

       public event TimeoutCaller TimeOver;

       
///<summary>
       
/// 开始时间
       
/// </summary>

       private DateTime _startTime;
       
private TimeSpan _timeout= new TimeSpan(0,0, 10);
       
private bool _hasStarted= false;
       
object _userdata;

       
///<summary>
       
/// 计时器构造方法
       
/// </summary>
       
/// <param name="userdata">计时结束时回调的用户数据</param>

       public Calculagraph(object userdata)
       
{
            TimeOver
+= new TimeoutCaller(OnTimeOver);
            _userdata
= userdata;
        }


       
///<summary>
       
/// 超时退出
       
/// </summary>
       
/// <param name="userdata"></param>

       public virtualvoid OnTimeOver(object userdata)
       
{
            Stop();
        }


       
///<summary>
       
/// 过期时间(秒)
       
/// </summary>

       public int Timeout
       
{
           
get
           
{
               
return _timeout.Seconds;
            }

           
set
           
{
               
if (value <= 0)
                   
return;
                _timeout
= new TimeSpan(0,0, value);
            }

        }


       
///<summary>
       
/// 是否已经开始计时
       
/// </summary>

       public bool HasStarted
       
{
           
get
           
{
               
return _hasStarted;
            }

        }


       
///<summary>
       
/// 开始计时
       
/// </summary>

       public void Start()
       
{
            Reset();
            _hasStarted
= true;
            Thread th
= new Thread(WaitCall);
            th.IsBackground
= true;
            th.Start();
        }


       
///<summary>
       
/// 重置
       
/// </summary>

       public void Reset()
       
{
            _startTime
= DateTime.Now;
        }


       
///<summary>
       
/// 停止计时
       
/// </summary>

       public void Stop()
       
{
            _hasStarted
= false;
        }


       
///<summary>
       
/// 检查是否过期
       
/// </summary>
       
/// <returns></returns>

       private bool checkTimeout()
       
{
           
return (DateTime.Now- _startTime).Seconds>= Timeout;
        }


       
private void WaitCall()
       
{
           
try
           
{
               
//循环检测是否过期
               while (_hasStarted&& !checkTimeout())
               
{
                    Thread.Sleep(
1000);
                }

               
if (TimeOver != null)
                    TimeOver(_userdata);
            }

           
catch (Exception)
           
{
                Stop();
            }

        }

    }


   
///<summary>
   
/// 过期时回调委托
   
/// </summary>
   
/// <param name="userdata"></param>

    public delegate void TimeoutCaller( object userdata);

     

    public class CNNWebClient : WebClient
   
{

       
private Calculagraph _timer;
       
private int _timeOut= 10;

       
///<summary>
       
/// 过期时间
       
/// </summary>

       public int Timeout
       
{
           
get
           
{
               
return _timeOut;
            }

           
set
           
{
               
if (value <= 0)
                    _timeOut
= 10;
                _timeOut
= value;
            }

        }


       
///<summary>
       
/// 重写GetWebRequest,添加WebRequest对象超时时间
       
/// </summary>
       
/// <param name="address"></param>
       
/// <returns></returns>

       protected override WebRequest GetWebRequest(Uri address)
       
{
            HttpWebRequest request
= (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout
= 1000 * Timeout;
            request.ReadWriteTimeout
= 1000 * Timeout;
           
return request;
        }


       
///<summary>
       
/// 带过期计时的下载
       
/// </summary>

       public void DownloadFileAsyncWithTimeout(Uri address,string fileName,object userToken)
       
{
           
if (_timer == null)
           
{
                _timer
= new Calculagraph(this);
                _timer.Timeout
= Timeout;
                _timer.TimeOver
+= new TimeoutCaller(_timer_TimeOver);
               
this.DownloadProgressChanged+= new DownloadProgressChangedEventHandler(CNNWebClient_DownloadProgressChanged);
            }


            DownloadFileAsync(address, fileName, userToken);
            _timer.Start();
        }


       
///<summary>
       
/// WebClient下载过程事件,接收到数据时引发
       
/// </summary>
       
/// <param name="sender"></param>
       
/// <param name="e"></param>

       void CNNWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
       
{
            _timer.Reset();
//重置计时器
        }


       
///<summary>
       
/// 计时器过期
       
/// </summary>
       
/// <param name="userdata"></param>

       void _timer_TimeOver(object userdata)
       
{
           
this.CancelAsync();//取消下载
        }

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值