WebClient的超时问题及解决

转自:http://blog.163.com/xiaozhi797@126/blog/static/62440288201112245345838/

 

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 virtual void 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();//取消下载
        }
    }

WebClient的超时问题及解决的更多相关文章

  1. ecshop运行超过30秒超时的限制解决办法

    ecshop运行超过30秒超时的限制解决办法 ECSHOP模板/ecshop开发中心(www.68ecshop.com) / 2014-06-04 ecshop运行超过服务器默认的设置30秒的限制时会 ...

  2. pip 安装出现超时问题的解决

    pip 安装出现超时问题的解决 我们在用默认的pip源进行安装python库时,会出现超时问题下载不了,如下图显示所示: 那么我们应该如何解决呢? 方法: 在自己电脑的  C:\Users\yanji ...

  3. C# WebClient 无法设置超时时间的解决办法

    http://www.lenashane.com/article/20150624-1021.html

  4. ssh超时断开的解决方法

    当用SSH Secure Shell连接Linux时,如果几分钟没有任何操作,连接就会断开,必须重新登陆才行,每次都重复相同的操作,很是烦人,本文总结了两种解决的方法. 方法1:更改ssh服务器的配置 ...

  5. Github网站加载不完全,响应超时,如何解决

    Github是一个代码托管平台和开发者社区,开发者可以在Github上创建自己的开源项目并与其他开发者协作编码.毫不夸张地说,高效利用Github是一个优秀的程序员必备的基本素质.可是,有的用户在打开 ...

  6. ssh登录等待时间超时问题的解决

    最近使用ssh登录服务器时,发现许多服务器会报告等待时间超时的错误,通过网上查找发现是由于ssh中的配置中开启了DNS反查的功能,导致在反查过程中消耗了很长的时间,现将解决方法总结如下: 使用root ...

  7. 一个有意思的Ruby Webdriver超时问题的解决过程

    rescue in receive 由于写ruby的时候感觉混身上下都拽起来了,所以比較喜欢用ruby写代码. 今天遇到了一个webdriver timeout的问题,问题本身还是由于我对webdri ...

  8. 连接FastDFS出现超时问题的解决办法

    1.使用Java语言写的web项目,jeecg框架连接FastDFS,需要修改的信息如下: # WEB-INF/classes/fdfs_client.conf connect_timeout=300 ...

  9. SSH 超时断开连接解决办法

    配置服务器端: vi /etc/ssh/sshd.conf ClientAliveInterval 120 #以秒为单位(可以改大些) ClientAliveCountMax 0 #发现客户端没有相应 ...

随机推荐

  1. Quarzt.NET的Cron表达式理解

    网上关于Quarzt.NET的Cron表达式介绍有很多,但都是基本的语法,稍微深入一些的就没有了. 基本语法介绍请参看: http://www.cnblogs.com/lzrabbit/archive ...

  2. 如何:确定调用 ASP.NET 网页的方式

    如何:确定调用 ASP.NET 网页的方式 通常有必要了解调用 ASP.NET 网页的方式:是由原始请求 (HTTP GET).回发 (HTTP POST).来自其他页的跨页面发送 (HTTP POS ...

  3. java remote debug

    1. java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000 -jar test.jar 2.会出现Listening for ...

  4. Js--AJAX的小知识(一):ajax的五种状态

    一.ajax的五种状态(readyState ) 0 - (未初始化)还没有调用send()方法 1 - (载入)已调用send()方法,正在发送请求 2 - (载入完成)send()方法执行完成,已 ...

  5. jBPM 6 开发 eclipse 插件安装

    jBPM 6 开发 eclipse 插件安装 概述 与之前的jBPM 5相比,jBPM 6 新引入的kjars及mavenized的特性,使流程开发设计与之前有了很大的不同,本文主要说明jBPM 6 ...

  6. ios开发中MVC模式的理解

    MVC是80年代出现的一种软件设计模式,是模型(model),视图(view)和控制(Controller)的缩写. 其中Model的主要功能包括业务逻辑的处理以及数据的访问,这是应用程序的主体部分. ...

  7. MATLAB中的函数的归总

    字符串操作函数 1.        函数eval可以用来执行用字符串表示的表达式 2.        函数deblank可以去掉字符串末尾的所有空格 3.        函数findstr可以用来在长 ...

  8. 问题:Bringing up interface eth0: Device eth0 does not seem to be present,delaying initialization. [FAILED]—— 找不到网卡。

    克隆虚拟机的时候或其他情况出现以下问题(命令service network restart):   Bringing up interface eth0:  Device eth0 does not ...

  9. html5+css3实现上拉和下拉刷新

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  10. 关于abbr 的一些用法

    <span style="margin: 20px;">位 000置:</span><abbr title='四川省绵阳市梓潼县文昌镇金龙乡一大队二组 ...