在 Stackoverflow 上看到了一个提问,关于并行的 WebClient,觉得回答者的代码很有参考性,下面记录一下,以便日后用到:

提问者:

我有一个功能基本上分为两个子功能。

html=RetriveHTML(int index);
returnColection = RegexProcess(html, index);

通过优化RetrieveHTML并列化来加速此过程的最佳方法是什么?

通常我用最多20000个索引来调用它。第一个subfuntcion是网络相关的(使用webclient.downloadstring从一个服务器获取几个URL HTML),第二个子功能主要是CPU。

我迷失在并行foreach和Tasks(继续,继续,fromasync)世界,我遇到麻烦来解决问题。我首先尝试使用Parallel foreach,但是我发现其性能即网络I / O在连续调用时会降级(第一个循环很快,其他循环变慢)。解决方案将释放html对象,因为它们很多很大。我正在使用.net 4.0

回答者:

    class Program
{
static void Main(string[] args)
{
ProcessInParallell();
} private static Regex _regex = new Regex("net"); private static void ProcessInParallell()
{
Uri[] resourceUri = new Uri[] { new Uri("http://www.microsoft.com"), new Uri("http://www.google.com"), new Uri("http://www.amazon.com") };
//1. Stage 1: Download HTML
//Use the blocking collection for concurrent tasks
BlockingCollection<string> htmlDataList = new BlockingCollection<string>();
Parallel.For(, resourceUri.Length, index =>
{
var html = RetrieveHTML(resourceUri[index]);
htmlDataList.TryAdd(html); //If we reach to the last index, signal the completion
if (index == (resourceUri.Length - ))
{
htmlDataList.CompleteAdding();
}
}); //2. Get matches
//This concurrent bags will be used to store the result of the matching stage
ConcurrentBag<string> matchedHtml = new ConcurrentBag<string>(); IList<Task> processingTasks = new List<Task>(); //Enumerate through each downloaded HTML document
foreach (var html in htmlDataList.GetConsumingEnumerable())
{
//Create a new task to match the downloaded HTML
var task = Task.Factory.StartNew((data) =>
{
var downloadedHtml = data as string;
if (downloadedHtml == null)
return;
if (_regex.IsMatch(downloadedHtml))
{
matchedHtml.Add(downloadedHtml);
}
},html);
//Add the task to the waiting list
processingTasks.Add(task);
} //wait for the all tasks to complete
Task.WaitAll(processingTasks.ToArray()); foreach (var html in matchedHtml)
{
//Do something with the matched result }
} private static string RetrieveHTML(Uri uri)
{
using (WebClient webClient = new WebClient())
{
//set this to null if there is no proxy
webClient.Proxy = null; byte[] data = webClient.DownloadData(uri); return Encoding.UTF8.GetString(data);
}
}
}

追问:

谢谢你的收获。但如果下载了很多/很长的html文件,这不会占用太多内存吗? -  husvar 2013年 1月23日21:58
 

回答:

我意识到如果下载的内容很大,就会占用大量内存。因此,您最好将工作量加大。干杯 -  Toan Nguyen 2013年1月23日22:45
 

谢谢浏览!

并行 Webclient(一)的更多相关文章

  1. .NET 实现并行的几种方式(三)

    本随笔续接:.NET 实现并行的几种方式(二) 在前两篇随笔中,先后介绍了 Thread .ThreadPool .IAsyncResult (即 APM系列) .Task .TPL (Task Pa ...

  2. C#的变迁史 - C# 5.0 之并行编程总结篇

    C# 5.0 搭载于.NET 4.5和VS2012之上. 同步操作既简单又方便,我们平时都用它.但是对于某些情况,使用同步代码会严重影响程序的可响应性,通常来说就是影响程序性能.这些情况下,我们通常是 ...

  3. 《C#并行编程高级教程》第9章 异步编程模型 笔记

    这个章节我个人感觉意义不大,使用现有的APM(异步编程模型)和EAP(基于时间的异步模型)就很够用了,针对WPF和WinForm其实还有一些专门用于UI更新的类. 但是出于完整性,还是将一下怎么使用. ...

  4. F# 天生就是就异步和并行的料

    做模型开发免不了要使用异步和并行计算,尤其在多核CPU的今天,更是如此,F#恰逢其时,天生就具备这种能力,先看一个例子. open System open System.Drawing open Sy ...

  5. Silverlight并行下载与串行下载

    思路清晰后仅仅只需百来行代码便可轻松编写出一套完整的资源动态下载组件- SerialDownloader和ParallelDownloader,它们共用一个完成资源表,且串行下载集成了优先机制(Dow ...

  6. 数据流(任务并行库 TPL)

    TPL 数据流库向具有高吞吐量和低滞后时间的占用大量 CPU 和 I/O 操作的应用程序的并行化和消息传递提供了基础. 它还能显式控制缓存数据的方式以及在系统中移动的方式. 为了更好地了解数据流编程模 ...

  7. 第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)

    一. 并行编程 1. 区分串行编程和串行编程 ①. 串行编程:所谓的串行编程就是单线程的作用下,按顺序执行.(典型代表for循环 下面例子从1-100按顺序执行) ②. 并行编程:充分利用多核cpu的 ...

  8. .NET 并行编程——任务并行

    本文内容 并行编程 任务并行 隐式创建和运行任务 显式创建和运行任务 任务 ID 任务创建选项 创建任务延续 创建分离的子任务 创建子任务 等待任务完成 组合任务 任务中的异常处理 取消任务 Task ...

  9. C#中的多线程 - 并行编程 z

    原文:http://www.albahari.com/threading/part5.aspx 专题:C#中的多线程 1并行编程Permalink 在这一部分,我们讨论 Framework 4.0 加 ...

随机推荐

  1. rabbitmq 实现多个消费队列

    1.将消费程序复制重新生成一个. 2.channel.BasicQos(0, 1, false); 空闲的先消费

  2. sql基础语句50条

    curdate() 获取当前日期 年月日 curtime() 获取当前时间 时分秒 sysdate() 获取当前日期+时间 年月日 时分秒 */ order by bonus desc limit ( ...

  3. Angular i18n(国际化方案)

    一.引言 i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称.在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无 ...

  4. 高性能TcpServer(C#) - 6.代码下载

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

  5. 基于rtmp+nginx 、vlc实现FFmpeg推流与wpf端拉流

    这周在研究基于rtmp+nginx直播流的实现,现总结如下: 0.所需文件: 链接:https://pan.baidu.com/s/1U5gsNI8Rcl684l5gVL6swg 提取码:dli9 1 ...

  6. 9.InfluxDB-InfluxQL基础语法教程--LIMIT and SLIMIT 子句

    本文翻译自官网,官网地址:(https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/) LIMIT和SLIM ...

  7. XGBoost 完整推导过程

    参考: 陈天奇-"XGBoost: A Scalable Tree Boosting System" Paper地址: <https://arxiv.org/abs/1603 ...

  8. [TCP/IP] TCP关闭连接为什么四次挥手

    1.建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端. 2.而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据 ...

  9. jenkins使用小技巧:jenkins构建出来的war/jar包如何带上SVN号?

    在实际使用过程中,一般会这样比如说打出来的包是 mypackage.jar, 但是每次打出来都是固定的 mypackage.jar如何来区分和上一个包的区别呢? 一般来说,会把打出来的包带上个 svn ...

  10. HBuilder创建app

    一.app登录注册实现 1.首先进行布局,mhead,mbody 在app index.html内创建一个 a链接通过mui.openWindow跳到登录页面 <a class="mu ...