最近更新了一个下载小工具,主要提升了下面几点:

1. 在一些分公司的局域网中,连接不上外网

2. 服务器上的文件更新后,下载到的还是更新前的文件

3. 没有下载进度提示

4. 不能终止下载

下面和大家分享一些心得。

鉴于各种复杂的网络环境,笔者决定采用不同的编程接口进行下载尝试,以增加程序的可用性。

这里仅介绍使用 WebClient 的方法,后续的文章会介绍其他的方法。博文中主要介绍思路和关键代码,完整的 demo 附在文末。

使用代理访问网络

很多公司的员工都是通过公司设置的代理上网的。通过代理上网主要是方便公司进行各种的管制,当然也能实现一些特殊的功能… 不过这会给我们的程序访问网络带来一些问题。

其实,WebClient 中的 API 已经很智能了,比如我们创建的 HttpWebRequest 对象,它自带一个 Proxy 属性。也就是说,WebHttpRequest 默认会使用找到的代理。这很棒,也能处理很多情况了。可是如果这个默认的代理需要验证域用户的身份信息,这时使用 WebHttpRequest 访问网络就可能失败。此时查看 Proxy. Credentials 属性,发现它是 null。

从 WebClient 的 API 中是可以取到系统默认的 Credentials 的,只是不太清楚为什么 Proxy.Credentials 属性默认没有设置为这个值。我们自己设置下就可以了。

request.Proxy.Credentials = CredentialCache.DefaultCredentials;

但实际的网络环境可能会更复杂,需要用户来指定联网的代理,并同时指定联网所需的 Credentials。写法如下:

myProxy = new WebProxy(“proxyAddress”);
myProxy.Credentials = new NetworkCredential(ProxyUserName, ProxyUserPasswd, DomainName);

克服缓存

缓存可谓无处不再,在服务器端 CDN 会有缓存,在客户端的代理层也会有缓存。所以经常出现的问题是:服务器上的文件明明更新了,还是会有一些客户下载到旧文件。我们先来处理客户端的缓存问题。

HttpWebRequest 的 CachePolicy.Level 属性就是设置缓存策略的,只是它的默认值是 BypassCache。我们把它改为 Reload 就行了:

request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload);

接下来是服务器端的缓存问题。

现在大家好像都在使用 CDN,可在使用中经常发现 CDN 端的缓存更新有问题。在网上查了查也没有什么好的解决办法,不过倒是有一个很好的 workaround,就是在请求中添加一个随机的字符串作为参数。

Random rdm = new Random();
string s = rdm.Next().ToString();
myUrl += "?" + s;

需要注意的是,关于缓存,一定要使用符合当前用例的策略,且不可搞一刀切。

更友好的下载过程

使用滚动条显示下载进度,显示实时的下载速度,允许用户取消下载:

aaarticlea/png;base64,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" alt="" />

下面是下载用的核心代码,我们把它分为计算下载百分比和计算当前下载速度分别介绍。

// 获得下载文件的长度
double contentLength = DownloadManager.GetContentLength(myHttpWebClient);
byte[] buffer = new byte[BufferSize];
long downloadedLength = ;
long currentTimeSpanDataLength = ;
int currentDataLength;
while ((currentDataLength = stream.Read(buffer, , BufferSize)) > && !this._cancelDownload)
{
fileStream.Write(buffer, , currentDataLength);
downloadedLength += (long)currentDataLength;
currentTimeSpanDataLength += (long)currentDataLength;
int intDownloadSpeed = ;
if (this._downloadStopWatch.ElapsedMilliseconds > )
{
double num5 = (double)currentTimeSpanDataLength / 1024.0;
double num6 = (double)this._downloadStopWatch.ElapsedMilliseconds / 1000.0;
double doubleDownloadSpeed = num5 / num6;
intDownloadSpeed = (int)Math.Round(doubleDownloadSpeed, );
this._downloadStopWatch.Reset();
this._downloadStopWatch.Start();
currentTimeSpanDataLength = ;
} double doubleDownloadPersent = 0.0;
if (contentLength > 0.0)
{
doubleDownloadPersent = (double)downloadedLength / contentLength;
}
}

在下载的过程中计算下载百分比

首先需要从 http 请求中获得要下载文件的长度,细节请参考本文所配 demo。

double contentLength = DownloadManager.GetContentLength(myHttpWebClient);

每从文件流中读取一次数据,我们知道读了多少个字节(currentDataLength),累计下来就是当前已经下载了的文件长度。

downloadedLength += (long)currentDataLength;

然后做个除法就行了:

doubleDownloadPersent = (double)downloadedLength / contentLength;

计算实时的下载速度

对于当前的下载速度,我们计算过去的一段时间内下载下来的字节数。时间段可以使用 StopWatch 来获得,我选择的时间段要求大于 800 毫秒。

if (this._downloadStopWatch.ElapsedMilliseconds > )
{
/***********************************/
// 计算上一个时间段内的下载速度
double num5 = (double)currentTimeSpanDataLength / 1024.0;
double num6 = (double)this._downloadStopWatch.ElapsedMilliseconds / 1000.0;
double doubleDownloadSpeed = num5 / num6;
/***********************************/ intDownloadSpeed = (int)Math.Round(doubleDownloadSpeed, );
// 本次网速计算完成后重置时间计时器和数据计数器,开始下次的计算
this._downloadStopWatch.Reset();
this._downloadStopWatch.Start();
currentTimeSpanDataLength = ;
}

事实上每次计算下载速度的时间段长度是不顾定的,但这并不影响计算结果,我只要保证距离上次计算超过了 800 毫秒就行了。

允许用户取消下载

对于一个执行时间比较长的任务来说,不允许用户取消它是被深恶痛绝的!尤其是网速不太好的时候。所以我们需要给用户一个选择:可以痛快(而不是痛苦)的结束当前的旅程。

而这一切对我们来说又是那么的简单!

while ((currentDataLength = stream.Read(buffer, , BufferSize)) >  && !this._cancelDownload){}

当从数据流中读取数据时,我们检查用户是不是按下了“取消”按钮,就是这里的 this._cancelDownload 变量。如果它是 true 就结束当前的下载。

至此,把用户抱怨最多的几个点都搞定了。其实也没有增加多少代码,并且每个知识点看起来都是那么的细微。但很明显的提高了用户的使用体验。这也给我们带来了一些启发,完成主要功能可能只是工作中的一部分,另外的一些工作可能并不是那么明显,需要我们不断的体会,发觉…

Demo 下载

C# 文件下载 : WebClient的更多相关文章

  1. C# 文件下载 : WinINet

    在 C# 中,除了 WebClient 我们还可以使用一组 WindowsAPI 来完成下载任务.这就是 Windows Internet,简称 WinINet.本文通过一个 demo 来介绍 Win ...

  2. powershell常用

    对于powershell,比较强大的shell,可以直接调用.net进行下载等等 get-command|where-object{$_.name -like 'write*'} get-wmiobj ...

  3. c# WebClient文件下载

    public void HttpDownload(string url, string path, ResourceType type) { using (var client = new WebCl ...

  4. Winform文件下载之WebClient

    最近升级了公司内部使用的一个下载小工具,主要提升了下面几点: 1. 在一些分公司的局域网中,连接不上外网 2. 服务器上的文件更新后,下载到的还是更新前的文件 3. 没有下载进度提示 4. 不能终止下 ...

  5. 使用WebClient类对网页下载源码,对文件下载保存及异步下载并报告下载进度

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAx4AAAI7CAIAAADtTtpYAAAgAElEQVR4nO3dX6xlV33Y8f3UJFUqHq

  6. WebClient实现文件下载详解(二)

    .Net2.0中新增了很多组件,WebClient就是其中一个,功能也很强大,今天拿WebClient做了一个小实验,只用到了一些很简单的功能就可以实现以前不好实现的功能,很方便. 简单介绍一下Web ...

  7. Winform文件下载之WinINet

    在C#中,除了webclient我们还可以使用一组WindowsAPI来完成下载任务.这就是Windows Internet,简称 WinINet.本文通过一个demo来介绍WinINet的基本用法和 ...

  8. WebClient.DownloadFile(线程机制,异步下载文件)

    线程机制(避免卡屏),异步下载文件. 我做网站的监控,WebClient.DownloadFile这个方法是我经常用到的,必要的时候肯定是要从网上下载些什么(WebRequest 也可以下载网络文件, ...

  9. C# 带进度条的文件下载

    private long fileLength; private long downLength;//已经下载文件大小,外面想用就改成公共属性 private static bool stopDown ...

随机推荐

  1. Lesson 13 The Greenwood Boys

    Text The Greenwood Boys are group of pop singers. At present, they are visiting all parts of the cou ...

  2. Curator Framework的基本使用方法

    Curator Framework提供了简化使用zookeeper更高级的API接口.它包涵很多优秀的特性,主要包括以下三点: 自动连接管理:自动处理zookeeper的连接和重试存在一些潜在的问题: ...

  3. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  4. Python学习笔记

    1. 进行浮点数运算时,整数要写成浮点数形式,否则Python默认按照整数进行运算了,譬如3/5应该写成3.0/5.0: 2. Python没有switch: 3. Python中没有重载,但是可以通 ...

  5. C# 6.0 功能预览 (一)

    一.索引的成员和元素初始化 1.1 原始初始化集合 Dictionary 1.2 键值初始化集合 Dictionary 1.3 运算符 $ 初始化集合 Dictionary 二.自动属性的初始化 一不 ...

  6. JavaScript实现TwoQueues缓存模型

    本文所指TwoQueues缓存模型,是说数据在内存中的缓存模型. 无论何种语言,都可能需要把一部分数据放在内存中,避免重复运算.读取.最常见的场景就是JQuery选择器,有些Dom元素的选取是非常耗时 ...

  7. js模版引擎handlebars.js实用教程——目录

    写在开头的话: 阅读本文需要了解基本的Handlebars.js概念,本文并不是Handlebars.js基础教程,而是注重于实际应用,为读者阐述使用过程中可能会遇到的一些问题. 实际上,小菜写这篇文 ...

  8. WCF basicHttpBinding之Message Security Mode

    原创地址:http://www.cnblogs.com/jfzhu/p/4067873.html 转载请注明出处 前面的文章<WCF Security基本概念>介绍了WCF的securit ...

  9. C语言 · Interval · 求矩阵元素和

    问题描述 这里写问题描述. 输入格式 测试数据的输入一定会满足的格式. 例:输入的第一行包含两个整数n, m,分别表示矩阵的行数和列数.接下来n行,每行m个正整数,表示输入的矩阵. 输出格式 要求用户 ...

  10. Objective-C 原型模式 -- 简单介绍和使用

    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建 ...