在 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. python网络编程-2

    1.理解相关概念 #浅显理解下 对比cpu与io的差距如:io从硬盘读取一条数据9ms ,cpu在9ms可以做450万次指令 cpu切换上下文的方式:1.遇到io操作切换cpu 2.cpu时间片分配 ...

  2. vue定时器+弹框 跳到登陆页面

    1.做一个请求拦截,并弹框提示几秒后,跳转到登陆首页或是点击确定之后直接跳转拦截用了this.$axios.interceptors.response页面上的弹框组件用了vux的组件vux地址:htt ...

  3. java Random类生成随机数

    封装一个方法: import java.util.Random; public class RandomUtil { /** * nextInt(num) 产生[0 ~ (num-1)]的随机数, 闭 ...

  4. Django forms 主要的标签介绍

    修改 forms.py from django import forms as DForms from django.forms import fields from django.forms imp ...

  5. 第15节_BLE协议GATT层

    学习资料:官方手册 Vol 3: Core System Package [Host volume] Part G: Generic Attribute Profile (GATT) 这篇文章格式比较 ...

  6. Spring(001)-Hello Spring

    Spring系列第一篇,先通过Spring实现一个Hello Spring程序. 访问 https://start.spring.io/ 开始spring代码骨架的构建. 输入mvn坐标 加入web和 ...

  7. destoon漏洞修复关于 $do->add($post); SQL注入修改

    在阿里云漏洞提示查看发现destoon有关于mobile/guestbook.php $do->add($post); SQL注入修改 漏洞名称:Destoon SQL注入 补丁文件:/mobi ...

  8. 多线程(五)多线程同步_Event事件

    事件和互斥体同样属于内核同步对象,它和互斥体以及临界区在功能上有以下区别 前面的互斥体和临界区主要作用在于确保控制多个线程之间对共享资源访问,保证共享资源的完整性 事件主要作用是通知其它线程一个操作己 ...

  9. ProxyPool 代理

    ProxyPool:https://github.com/yucaifuyoyo/ProxyPool github上一个开源项目的proxypool添加一些免费代理IP网站 1.https://www ...

  10. 【电脑】XSHELL破解

    序列号