一个简单的利用 WebClient 异步下载的示例(三)
继续上一篇 一个简单的利用 WebClient 异步下载的示例(二) 后,继续优化它。
1. 直接贴代码了:
DownloadEntry:
public class DownloadEntry
{
public string Url { get; set; } public string Path { get; set; } /// <summary>
/// 当前处理的数据
/// </summary>
public object Data { get; set; } public DownloadEntry(string url, string savedPath)
: this(url, savedPath, null)
{ } public DownloadEntry(string url, string savedPath, object data)
{
Url = url;
Path = savedPath;
Data = data;
}
}
SkyParallelWebClient 类:
/// <summary>
/// 并行的 WebClient
/// </summary>
public class SkyParallelWebClient
{
ConcurrentQueue<DownloadEntry> OptionDataList = new ConcurrentQueue<DownloadEntry>(); public SkyParallelWebClient(ICollection<DownloadEntry> downloadConfigs)
{
if (downloadConfigs == null)
{
throw new ArgumentNullException("downloadConfigs");
}
foreach (var item in downloadConfigs)
{
OptionDataList.Enqueue(item);
}
} public bool TryStart(int parallelCount)
{
string errorMessage;
return TryStart(parallelCount, out errorMessage);
} public bool TryStart(int parallelCount, out string errorMessage)
{
try
{
StartCore(parallelCount);
errorMessage = null;
return true;
}
catch (Exception ex)
{
errorMessage = ex.Message;
return false;
}
} protected void StartCore(int takeCount)
{
if (OptionDataList.Count == )
{
return;
}
IList<Task> processingTasks = new List<Task>();
for (int i = ; i < takeCount; i++)
{
if (OptionDataList.Count == )
{
break;
}
DownloadEntry downloadEntry;
if (!OptionDataList.TryDequeue(out downloadEntry))
{
break;
}
var task = Task.Factory.StartNew((data) =>
{
DownloadEntry temp = data as DownloadEntry;
if (downloadEntry == null)
return;
DownloadFile(temp);
}, downloadEntry);
processingTasks.Add(task);
}
Task.WaitAll(processingTasks.ToArray());
if (OptionDataList.Count > )
{
StartCore(takeCount);
}
} private static void DownloadFile(DownloadEntry downloadEntry)
{
using (WebClient webClient = new WebClient())
{
//set this to null if there is no proxy
webClient.Proxy = null; webClient.DownloadFile(new Uri(downloadEntry.Url), downloadEntry.Path);
}
}
}
客户端测试代码:
private void btnRunByWebClient_Click(object sender, EventArgs e)
{
WhenAllDownloading();
var ids = GetDownloadIds();
List<DownloadEntry> downloadConfigs = new List<DownloadEntry>();
Random rd = new Random();
foreach (var id in ids)
{
downloadConfigs.Add(new DownloadEntry(TaskDemo101.GetRandomUrl(rd), TaskDemo101.GetSavedFileFullName(), id));
}
ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncRunSkyParallelWebClient), downloadConfigs);
} private void AsyncRunSkyParallelWebClient(object state)
{
SkyParallelWebClient skyParallelWebClient = new SkyParallelWebClient((List<DownloadEntry>)state);
string errorMessage;
if (!skyParallelWebClient.TryStart(, out errorMessage))
{
MessageBox.Show(errorMessage);
return;
}
WhenAllDownloaded();
}
2. 效果图
由于并行后,无法统计下载进度,所以没有进度条了。注意:每一项完成后,没有日志,也就是说下面的 “编号 99 下载 True”是不会有的!

3. 总结
以上测试可以解决并行下载的任务,且体验相对来说比较好。但有一个不完美的地方,就是该任务以一定量(比如:20个)任务为一个单元,只要这个单元中有一个任务耗费了太多太多时间,即使其它 19 个任务都非常快速地完成了,也要等在那里。下篇文章,我们将再次完善它。
谢谢浏览!
一个简单的利用 WebClient 异步下载的示例(三)的更多相关文章
- 一个简单的利用 WebClient 异步下载的示例(二)
继上一篇 一个简单的利用 WebClient 异步下载的示例(一) 后,我想把核心的处理提取出来,成 SkyWebClient,如下: 1. SkyWebClient 该构造函数中 downloadC ...
- 一个简单的利用 WebClient 异步下载的示例(一)
继上一篇文章 一个简单的利用 HttpClient 异步下载的示例 ,我们知道不管是 HttpClient,还算 WebClient,都不建议每次调用都 new HttpClient,或 new We ...
- 一个简单的利用 WebClient 异步下载的示例(五)(完结篇)
接着上一篇,我们继续来优化.我们的 SkyParallelWebClient 可否支持切换“同步下载模式”和“异步下载模式”呢,好处是大量的代码不用改,只需要调用 skyParallelWebClie ...
- 一个简单的利用 WebClient 异步下载的示例(四)
接上一篇,我们继续优化它. 1. DownloadEntry 类 public class DownloadEntry { public string Url { get; set; } public ...
- 一个简单的利用 HttpClient 异步下载的示例
可能你还会喜欢 一个简单的利用 WebClient 异步下载的示例 ,且代码更加新. 1. 定义自己的 HttpClient 类. using System; using System.Collec ...
- VC6下OpenGL 开发环境的构建外加一个简单的二维网络棋盘绘制示例
一.安装GLUT 工具包 GLUT 不是OpenGL 所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows 环境下的GLUT 本地下载地址:glut-install.zip(大小约为 ...
- [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(三)
一步步打造一个简单的 MVC 电商网站 - BooksStore(三) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
- 一个简单的AXIS远程调用Web Service示例
我们通常都将编写好的Web Service发布在Tomcat或者其他应用服务器上,然后通过浏览器调用该Web Service,返回规范的XML文件.但是如果我们不通过浏览器调用,而是通过客户端程序调用 ...
- [c#]WebClient异步下载文件并显示进度
摘要 在项目开发中经常会用到下载文件,这里使用winform实现了一个带进度条的例子. 一个例子 using System; using System.Collections.Generic; usi ...
随机推荐
- 零基础学python,python视频教程
零基础学python,python视频教程 这是我收集到的互联网上的视频资源,所有内容均来自互联网.仅供学习使用. 目前我在也在学习过程中,会把学习过程中遇到问题以及解决问题的方式,总结到我的公众号[ ...
- 转Ubuntu 16.04 创建无线热点
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ac_dao_di/article/deta ...
- PHP获取网址详情页的内容导出到WORD文件
亲自测试效果一般, css的样式文件获取不到 如果没有特殊的样式 或者是内容里面包括样式的 直接输出有样式的内容 然后导出 这样还是可以的 class word { function start ...
- .net 定时任务调度
前段时间开发个项目需要自定义时间定时发送邮件,此处使用了Quartz 定时任务,在此记录下: /// <summary> /// 创建定时任务 /// </summary> / ...
- python基础(22):模块、包
1. 模块 1.1 什么是模块 别人写好的函数.变量.方法放在一个文件里 (这个文件可以被我们直接使用)这个文件就是个模块 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模 ...
- linux用户管理章节笔记
1 更改有效用户组 :newgrp zeng 把当前用户的有效用户组更改为zeng.事后可以使用groups命令查看. 2 在使用useradd命令增加用户时,在/etc/passwd的值一般会参考 ...
- [转]Spring Cloud在国内中小型公司能用起来吗?
原文地址:http://www.cnblogs.com/ityouknow/p/7508306.html 原文地址:https://www.zhihu.com/question/61403505 今天 ...
- 第十二章 WEB渗透
Web技术发展 • 静态WEB• 动态WEB • 应用程序 • 数据库 • 每个人看到的内容不同 • 根据用户输入返回不同结果 WEB攻击面• Network• OS• WEB Server• App ...
- Java JDK 运行环境安装
1 Windows系统 1.1 安装包准备 安装包本文档讲解为64位系统,如果是32位系统需要下载32位系统安装包 1.1.1 下载方式 打开jdk官方下载地址,该文档提供jdk版本为1.8 http ...
- Python学习笔记2基本语法规则_20170611
# 1.print 显示示例 print('Hello, World!') 逗号分割变量,输出插入空格 name = 'BB' print('AA', name) # output: >> ...