热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#学习教程:并行请求刮取网站的多个页面分享

并行请求刮取网站的多个页面我想用一个包含大量有趣数据页面的网站,但由于源非常大,我想multithreading并限制过载。我使用Parallel.ForEach来启动10个任务的

并行请求刮取网站的多个页面

我想用一个包含大量有趣数据页面的网站,但由于源非常大,我想multithreading并限制过载。 我使用Parallel.ForEach来启动10个任务的每个块,然后在main for循环中等待,直到活动线程的数量开始下降到阈值以下。 为此我使用活动线程的计数器,我在使用WebClient启动新线程时递增,并在触发WebClientDownloadStringCompleted事件时递减。

最初的问题是如何使用DownloadStringTaskAsync而不是DownloadString并等待Parallel.ForEach启动的每个线程都已完成。 这已通过一种解决方法解决:主要foor循环中的计数器( activeThreads )和Thread.Sleep

使用await DownloadStringTaskAsync而不是DownloadString应该通过在等待DownloadString数据到达时释放线程来提高速度吗?

回到原来的问题,是否有办法更优雅地使用TPL,而没有涉及计数器的解决方法?

 private static volatile int activeThreads = 0; public static void RecordData() { var nbThreads = 10; var source = db.ListOfUrls; // Thousands urls var iteratiOns= source.Length / groupSize; for (int i = 0; i  RecordUri(item)); //I want to wait here until process further data to avoid overload while (activeThreads > 30) Thread.Sleep(100); } } private static async Task RecordUri(Uri uri) { using (WebClient wc = new WebClient()) { Interlocked.Increment(ref activeThreads); wc.DownloadStringCompleted += (sender, e) => Interlocked.Decrement(ref iterationsCount); var jsOnData= ""; RootObject root; jsOnData= await wc.DownloadStringTaskAsync(uri); var root = JsonConvert.DeserializeObject(jsonData); RecordData(root) } } 

如果您想要一个优雅的解决方案,您应该使用Microsoft的Reactive Framework。 这很简单:

 var source = db.ListOfUrls; // Thousands urls var query = from uri in source.ToObservable() from jsonData in Observable.Using( () => new WebClient(), wc => Observable.FromAsync(() => wc.DownloadStringTaskAsync(uri))) select new { uri, json = JsonConvert.DeserializeObject(jsonData) }; IDisposable subscription = query.Subscribe(x => { /* Do something with x.uri && x.json */ }); 

这就是整个代码。 这是很好的multithreading,它一直在控制之下。

只需NuGet“System.Reactive”即可得到这些位。

 Parallel.ForEach 

将创建ProcessorCount任务以执行源Enumerable中每个项目的function。 它将注意没有很多任务,并将等待执行所有项目和任务。

 Task.WhenAll 

只等待给定的任务,它不执行它们。 在你的手上以正确的方式执行它们而不是一次执行它们。

但是你的代码有一些错误。 函数RecordUri将返回一个必须等​​待的任务,否则ForEach将创建越来越多的函数,因为函数永远不会知道当前任务何时完成。 同样有问题的是,您在任务中创建任务,第一个任务不执行任何操作,然后等待第一个任务。

您可能还想看看Parallel.ForEach这个重载https://msdn.microsoft.com/en-us/library/dd782934(v=vs.110).aspx

编辑

使用等待DownloadStringTaskAsync而不是DownloadString应该通过在等待DownloadString数据到达时释放线程来提高速度吗?

否。当任务正在等待外部资源时,它进入Suspended状态(Windows api没有使用某些旧的/脏迭代等待)。 所以没有太大区别。 不同之处在于编译异步代码时编译器将产生的开销。 DownloadStringTaskAsync将创建包含长操作的任务。 如果您使用等待它,您将自己附加到该任务(通过ContinueWith)。 所以你只需创建一个等待另一个的任务。 这是我在上部文本中讨论的开销。

我的方法是:在Parallel.ForEach中使用同步方法 。 线程将由PLinq完成,您可以自由继续。

记住“亲吻”

上述就是C#学习教程:并行请求刮取网站的多个页面分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—编程笔记


推荐阅读
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • Silverlight 实战指南:深入解析用户提交数据的验证与捕获机制
    本文深入探讨了Silverlight中用户提交数据的验证与捕获机制,详细分析了四种主要的验证方法:基本异常处理、DataAnnotation注解、IDataErrorInfo客户端同步验证以及自定义验证策略。通过实例解析,帮助开发者更好地理解和应用这些机制,提升应用程序的数据处理能力和用户体验。 ... [详细]
  • WPF项目学习.一
    WPF项目搭建版权声明:本文为博主初学经验,未经博主允许不得转载。一、前言记录在学习与制作WPF过程中遇到的解决方案。使用MVVM的优点是数据和视图分离,双向绑定,低耦合,可重用行 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 本教程详细介绍了如何使用 Spring Boot 创建一个简单的 Hello World 应用程序。适合初学者快速上手。 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在 Ubuntu 中遇到 Samba 服务器故障时,尝试卸载并重新安装 Samba 发现配置文件未重新生成。本文介绍了解决该问题的方法。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 本文探讨了在PHP中实现MySQL分页查询功能的优化方法与实际应用。通过详细分析分页查询的常见问题,提出了多种优化策略,包括使用索引、减少查询字段、合理设置缓存等。文章还提供了一个具体的示例,展示了如何通过优化模型加载和分页参数设置,显著提升查询性能和用户体验。 ... [详细]
author-avatar
mobiledu2502859163
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有