当前位置: 首页 > news >正文

增强WebClient的同步下载功能

WebClient是一个功能强大的类,通过直接使用或继承它可以很容易的下载各种Http和Ftp资源。在客户端程序中,我一般使用的是同步下载的方式来下载文件,然而WebClient的同步下载方法稍微薄弱了些,使得其在下载大文件方面存在很大的不足,主要体现在如下方面:

  1. 下载的时候无法取消
  2. 无法获取到下载速度

其实要实现这两方面的控制主要是要实现对ResponseStream的控制即可,然而,WebClient没有从一个统一的入口来获取ResponseStream,并不能通过简单的继承WebClient来实现该功能,因此,还需要对WebRequest进行封装,在WebRequest中返回封装的Stream,通过新的Stream实现对下载的控制(稍微修改一下也可以支持异步的)。基本形式如下:

class WebClientPlus:WebClient
{
    protected override WebResponse GetWebResponse(WebRequest request)
    {
        return base.GetWebResponse(request);
    }
}

class WebRepuestPlus:WebRequest
{
    WebRequest request;
    public WebRepuestPlus(WebRequest request)
    {
        this.request = request;
    }

    public override System.IO.Stream GetRequestStream()
    {
        return base.GetRequestStream();
    }
}

class WebStreamPlus:System.IO.Stream
{
    System.IO.Stream stream;

    public WebStreamPlus(System.IO.Stream stream)
    {
        this.stream = stream;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {

        //这里可以实现速度的计算
        return stream.Read(buffer, offset, count);
    }
}

这样做后,可以通过修改代码,在WebClientPlus中保留对的WebStreamPlus引用,同时增强WebStreamPlus的功能,实现下载速度的计算(关闭直接调用其Close方法即可)。这样,就可以很容易实现我们所需要的功能了。

这种思路其实还是比较简单,就是要实现两个代理类:WebStreamPlusWebRepuestPlus。这种代理类实现简单,写起来却较麻烦,如果用代码生成器来生成比较合适(目前还没有这种代码生成器,其实用反射写这种代码生成器应该不难)。(上面的代码只是一个示意,并没有写完

按照这种思路,实现上传时候的控制也是很简单的。同样,也可以很容易扩展Webclient的功能,如对下载文件在内存中进行缓存、自动多次重连、断点续传等常用的下载功能。

相关文章:

  • redis集群以及测试
  • CSS Hack 汇总快查
  • 针对小程序for循环绑定数据,实现toggle切换效果(交流QQ群:604788754)
  • 50分,再求兩個BCB轉delphi的問題,非常感謝!
  • IEnumerable 和 IEnumerator 接口
  • Ionic 入门与实战之第三章:Ionic 项目结构以及路由配置
  • 使用HBuilder编辑器进行真机调试运行时提示Waiting for debugger!
  • 交换机端口安全
  • SQLite入门与分析(四)---Page Cache之事务处理(2)
  • Windows上为Apache配置HTTPS
  • [数据恢复答疑]IBM 的RAID5E和RAID5EE适合我吗?
  • 【LeeCode】Two Sum
  • Alexnet参数解释
  • es6的常用语法
  • asp.net 点击girdView中的超链接列复制地址--源码--调试成功
  • hexo+github搭建个人博客
  • SegmentFault for Android 3.0 发布
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • Angular2开发踩坑系列-生产环境编译
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • JAVA 学习IO流
  • JavaScript对象详解
  • JavaScript类型识别
  • JS基础之数据类型、对象、原型、原型链、继承
  • Redash本地开发环境搭建
  • vue2.0项目引入element-ui
  • vue-cli3搭建项目
  • 从tcpdump抓包看TCP/IP协议
  • 设计模式 开闭原则
  • 使用 QuickBI 搭建酷炫可视化分析
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​批处理文件中的errorlevel用法
  • (二十三)Flask之高频面试点
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (力扣)循环队列的实现与详解(C语言)
  • (强烈推荐)移动端音视频从零到上手(下)
  • (十八)SpringBoot之发送QQ邮件
  • (十六)Flask之蓝图
  • (四) 虚拟摄像头vivi体验
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)母版页和相对路径
  • (转载)Linux网络编程入门
  • ./configure,make,make install的作用
  • .java 9 找不到符号_java找不到符号
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net2005怎么读string形的xml,不是xml文件。
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .net连接MySQL的方法