在 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. CSS样式表及选择器相关内容(二)-伪类与伪元素选择器

    伪类与伪元素选择器归纳: 一.伪类选择器(伪类以":"开头,用在选择器后,用于指明元素在某种特殊的状态下才能被选中)    1.a标签伪类选择器,其他标签类似        eg: ...

  2. uni-app学习(六)好用的插件4

    1. uni-app学习(六)好用的插件4 1.1. QQ音乐模板 点击这里 示例 1.2. 画廊(ynGallery)组件 点击这里 看起来不错的 示例 1.3. 评价模板 学到个动画用法 imag ...

  3. leetcode - 使用栈实现队列的特性

    使用栈实现队列的特性 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() - ...

  4. [b0013] Hadoop 版hello word mapreduce wordcount 运行(三)

    目的: 不用任何IDE,直接在linux 下输入代码.调试执行 环境: Linux  Ubuntu Hadoop 2.6.4 相关: [b0012] Hadoop 版hello word mapred ...

  5. js 实现JSONP

    编写一个 jsonp.html 内容如下: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  6. SQL server 无法更新标识列

    若是数据库设置了自增长字段,相应的Model也要做标记,否则修改数据的时候会提示无法更新条目 /// <summary> /// 自增长ID /// </summary> [D ...

  7. Python从零开始——循环语句

    一:Python循环语句知识概览 二:while循环 三:for遍历 四:循环控制

  8. Jenkins + Pipeline + Git + Maven (十)

    一.准备环境介绍 192.168.5.71 # gitlab 仓库IP 192.168.5.72 # 开发环境,用于提交代码等 192.168.5.73 # tomcat 部署solo服务站点 192 ...

  9. 7. Transformer-XL原理介绍

    1. 语言模型 2. Attention Is All You Need(Transformer)算法原理解析 3. ELMo算法原理解析 4. OpenAI GPT算法原理解析 5. BERT算法原 ...

  10. 201871010106-丁宣元 《面向对象程序设计(java)》第七周学习总结

    201871010106-丁宣元 <面向对象程序设计(java)>第七周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://home.cnblogs.com/u/nwn ...