继上一篇文章 一个简单的利用 HttpClient 异步下载的示例 ,我们知道不管是 HttpClient,还算 WebClient,都不建议每次调用都 new HttpClient,或 new WebClient,而应该尽量重复对象,可以把一个 WebClient(或 HttpClient)理解成一个浏览器,不能没打开一个页面以后,就销毁它,再重新创建一个,这样会有性能损失,而建议一个线程共用一个 WebClient(或 HttpClient)。这一次,我们利用 WebClient 来实现异步下载,这一次,我们增加一个进度条来显示进度。

直接提代码了:

1. TaskDemo101

优化后的 TaskDemo101 类:

     public static class TaskDemo101
{
public static string GetRandomUrl()
{
string url1 = "http://www.xxx.me/Uploads/image/20130129/2013012920080761761.jpg";
string url2 = "http://www.xxx.me/Uploads/image/20121222/20121222230686278627.jpg";
string url3 = "http://www.xxx.me/Uploads/image/20120606/20120606222018461846.jpg";
string url4 = "http://www.xxx.me/Uploads/image/20121205/20121205224383848384.jpg";
string url5 = "http://www.xxx.me/Uploads/image/20121205/20121205224251845184.jpg"; string resultUrl;
int randomNum = new Random().Next(, );
switch (randomNum)
{
case : resultUrl = url1; break;
case : resultUrl = url2; break;
case : resultUrl = url3; break;
case : resultUrl = url4; break;
case : resultUrl = url5; break;
default: throw new Exception("");
}
return resultUrl;
} public static string GetSavedFileFullName()
{
string targetFolderDestination = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "downloads\\images\\");
try
{
Directory.CreateDirectory(targetFolderDestination);
}
catch (Exception)
{
Console.WriteLine("创建文件夹失败!");
}
string targetFileDestination = Path.Combine(targetFolderDestination, string.Format("img_{0}.png", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")));
return targetFileDestination;
} public static async Task<bool> RunByHttpClient(SkyHttpClient skyHttpClient, int id)
{
var task = skyHttpClient.DownloadImage(GetRandomUrl());
return await task.ContinueWith<bool>(t => {
File.WriteAllBytes(GetSavedFileFullName(), t.Result);
return true;
});
} public static void RunByWebClient(WebClient webClient, int id)
{
webClient.DownloadFileAsync(new Uri(GetRandomUrl()), GetSavedFileFullName());
}
}

2. Form1

这一次我们的 Form1 实现了 INotifyPropertyChanged 接口

    public partial class Form1 : Form, INotifyPropertyChanged
{
#region 字段、属性 public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
WebClient webc = new WebClient();
bool _canChange = true;
public bool CanChange
{
get
{
return _canChange;
}
set
{
_canChange = value;
OnPropertyChanged("CanChange");
}
} #endregion public Form1()
{
InitializeComponent();
webc.DownloadFileCompleted += Webc_DownloadFileCompleted; //注册下载完成事件
webc.DownloadProgressChanged += Webc_DownloadProgressChanged; //注册下载进度改变事件
} private List<int> GetDownloadIds()
{
List<int> ids = new List<int>();
for (int i = ; i <= ; i++)
{
ids.Add(i);
}
return ids;
} private void WhenAllDownloading()
{
this.listBoxLog.Items.Insert(, string.Format("当前时间:{0},准备开始下载...", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
//禁用按钮
EnableOrDisableButtons(false);
} private void EnableOrDisableButtons(bool enabled)
{
this.btnRunByHttpClient.Enabled = enabled;
this.btnRunByWebClient.Enabled = enabled;
} private void WhenSingleDownloaded(int id, bool singleDownloadSuccess)
{
this.listBoxLog.Items.Insert(, string.Format("当前时间:{0},编号 {1} 下载 {2}!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), id, singleDownloadSuccess));
} private void WhenAllDownloaded()
{
this.listBoxLog.Items.Insert(, string.Format("当前时间:{0},下载完毕!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
//启用按钮
EnableOrDisableButtons(true);
} private async void btnRunByHttpClient_Click(object sender, EventArgs e)
{
SkyHttpClient skyHttpClient = new SkyHttpClient();
try
{
WhenAllDownloading();
foreach (var id in GetDownloadIds())
{
bool singleDownloadSuccess = await TaskDemo101.RunByHttpClient(skyHttpClient, id);
WhenSingleDownloaded(id, singleDownloadSuccess);
}
WhenAllDownloaded();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Download Error!");
}
} private void btnRunByWebClient_Click(object sender, EventArgs e)
{
if (CanChange)
{
WhenAllDownloading();
CanChange = false; ToDownload.Clear();
foreach (var id in GetDownloadIds())
{
ToDownload.Enqueue(id);
} progressBar1.Maximum = ToDownload.Count * ;
btnRunByWebClient.Text = "用 WebClient 暂停下载"; int firstId = ToDownload.Dequeue();
TaskDemo101.RunByWebClient(webc, firstId);
WhenSingleDownloaded(firstId, true);
}
else
{
ToDownload.Clear();
webc.CancelAsync();
CanChange = true;
progressBar1.Value = ;
btnRunByWebClient.Text = "用 WebClient 开始下载";
}
} private void Webc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null && !e.Cancelled)
{
MessageBox.Show("下载时出现错误: " + e.Error.Message);
CanChange = true;
progressBar1.Value = ;
}
else
{
DownloadNext();
}
} private void Webc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Value = progressBar1.Maximum - ((ToDownload.Count + ) * ) + e.ProgressPercentage;
} Queue<int> ToDownload = new Queue<int>(); private void DownloadNext()
{
if (ToDownload.Any())
{
int nextId = ToDownload.Dequeue();
TaskDemo101.RunByWebClient(webc, nextId);
WhenSingleDownloaded(nextId, true);
progressBar1.Value = progressBar1.Maximum - ((ToDownload.Count + ) * );
}
else
{
MessageBox.Show("全部下载完成");
CanChange = true;
progressBar1.Value = ;
btnRunByWebClient.Text = "用 WebClient 开始下载";
WhenAllDownloaded();
}
}
}

3. 运行截图

如图:

下载完成以后:

谢谢浏览!

一个简单的利用 WebClient 异步下载的示例(一)的更多相关文章

  1. 一个简单的利用 WebClient 异步下载的示例(三)

    继续上一篇 一个简单的利用 WebClient 异步下载的示例(二) 后,继续优化它. 1. 直接贴代码了: DownloadEntry: public class DownloadEntry { p ...

  2. 一个简单的利用 WebClient 异步下载的示例(二)

    继上一篇 一个简单的利用 WebClient 异步下载的示例(一) 后,我想把核心的处理提取出来,成 SkyWebClient,如下: 1. SkyWebClient 该构造函数中 downloadC ...

  3. 一个简单的利用 WebClient 异步下载的示例(五)(完结篇)

    接着上一篇,我们继续来优化.我们的 SkyParallelWebClient 可否支持切换“同步下载模式”和“异步下载模式”呢,好处是大量的代码不用改,只需要调用 skyParallelWebClie ...

  4. 一个简单的利用 WebClient 异步下载的示例(四)

    接上一篇,我们继续优化它. 1. DownloadEntry 类 public class DownloadEntry { public string Url { get; set; } public ...

  5. 一个简单的利用 HttpClient 异步下载的示例

    可能你还会喜欢 一个简单的利用 WebClient 异步下载的示例  ,且代码更加新. 1. 定义自己的 HttpClient 类. using System; using System.Collec ...

  6. VC6下OpenGL 开发环境的构建外加一个简单的二维网络棋盘绘制示例

    一.安装GLUT 工具包 GLUT 不是OpenGL 所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows 环境下的GLUT 本地下载地址:glut-install.zip(大小约为 ...

  7. 一个简单的AXIS远程调用Web Service示例

    我们通常都将编写好的Web Service发布在Tomcat或者其他应用服务器上,然后通过浏览器调用该Web Service,返回规范的XML文件.但是如果我们不通过浏览器调用,而是通过客户端程序调用 ...

  8. [c#]WebClient异步下载文件并显示进度

    摘要 在项目开发中经常会用到下载文件,这里使用winform实现了一个带进度条的例子. 一个例子 using System; using System.Collections.Generic; usi ...

  9. WebClient异步下载文件

    namespace ConsoleAppSyncDownload{    class Program    { static void Main(string[] args)        {     ...

随机推荐

  1. 数据库——SQL-SERVER练习(1)连接与子查询

    一.实验准备 1.复制实验要求文件及“CREATE-TABLES.SQL”文件, 粘贴到本地机桌面. 2.启动SQL-SERVER服务. 3. 运行查询分析器, 点击菜单<文件>/< ...

  2. HTTP 响应的分块传输

    Transfer-Encoding 响应头用于告诉客户端服务器发送内容的编码格式. 其可选值有: chunked:数据分块发送.此时应缺省 Content-Length 响应头. compress:使 ...

  3. MVC过滤器:自定义异常过滤器

    一.异常过滤器 异常筛选器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行.异常筛选器可用于执行诸如日志记录或显示错误页之类的任务.Hand ...

  4. C# Newtonsoft.Json 读取文件,返回json字符串

    第一种方法: public object getData2() { string content; using (StreamReader sr = new StreamReader(Server.M ...

  5. Web前端基础(1):HTML(一)

    1. HTML概述 1.1 什么是HTML HTML称为超文本标记语言,是一种标识性的语言.它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整体.H ...

  6. springMVC校验器(validator)

    springmvc使用的是Hibernate Validator(和Hibernate的ORM无关)来完成校验功能 一.普通校验 1.导入jar包 2.编写校验错误配置文件 3.配置校验错误信息文件 ...

  7. log4j笔记----输出格式

    数说明例子 %c 列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间 log4j配置文件参数举例 输出显示媒介 假设当前logger名字空间是&q ...

  8. Dynamics CRM 客户端程序开发:自定义系统标准按钮的可用性

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复125或者20140414可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 一般是新建一个解决方案用于客制化 ...

  9. REST API接口测试

    背景介绍 为什么要做借口测试? 很多系统关联都是基于接口来实现的,接口测试可以将复杂的系统关联进行简化. 接口功能比较单一,能够比较好的进行测试覆盖,也相对容易实现自动化持续集成. 接口相当于界面功能 ...

  10. 6.Java基础_Java自增自减/关系/逻辑/三元运算符

    /* 自增自减运算符 关系运算符 逻辑运算符 三元运算符 (同C++) */ public class OperatorDemo01 { public static void main(String[ ...