zoukankan      html  css  js  c++  java
  • WebClient的超时问题及解决

    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();//取消下载
            }
        }
  • 相关阅读:
    linux执行命令并获取结果(system)
    awk----基本用法
    shell用法总结
    autoit(au3)使用说明
    博客搜集
    vi常用快捷键总结
    python简单学------------程序传参数,列表推导式,set、list、tuple 转换
    python简单学------------模块
    python简单学------------python面向对象(3)
    python简单学------------python面向对象(2)
  • 原文地址:https://www.cnblogs.com/elim/p/3848472.html
Copyright © 2011-2022 走看看