针对多个 Web 请求的最佳多线程方法

2024-01-02

我想创建一个程序来爬行并检查我的网站是否有 http 错误和其他内容。 我想使用多个线程来执行此操作,这些线程应该接受要抓取的 url 等参数。 虽然我希望 X 线程处于活动状态,但仍有 Y 任务正在等待执行。

现在我想知道执行此操作的最佳策略是什么:线程池、任务、线程还是其他策略?


下面的示例展示了如何对一堆任务进行排队,但限制同时运行的数量。它使用一个Queue跟踪准备运行的任务并使用Dictionary跟踪正在运行的任务。当任务完成时,它会调用回调方法将其自身从任务中删除Dictionary. An async方法用于在空间可用时启动排队任务。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MinimalTaskDemo
{
    class Program
    {
        private static readonly Queue<Task> WaitingTasks = new Queue<Task>();
        private static readonly Dictionary<int, Task> RunningTasks = new Dictionary<int, Task>();
        public static int MaxRunningTasks = 100; // vary this to dynamically throttle launching new tasks 

        static void Main(string[] args)
        {
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            Worker.Done = new Worker.DoneDelegate(WorkerDone);
            for (int i = 0; i < 1000; i++)  // queue some tasks
            {
                // task state (i) will be our key for RunningTasks
                WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((int)id, token), i, token));
            }
            LaunchTasks();
            Console.ReadKey();
            if (RunningTasks.Count > 0)
            {
                lock (WaitingTasks) WaitingTasks.Clear();
                tokenSource.Cancel();
                Console.ReadKey();
            }
        }

        static async void LaunchTasks()
        {
            // keep checking until we're done
            while ((WaitingTasks.Count > 0) || (RunningTasks.Count > 0))
            {
                // launch tasks when there's room
                while ((WaitingTasks.Count > 0) && (RunningTasks.Count < MaxRunningTasks))
                {
                    Task task = WaitingTasks.Dequeue();
                    lock (RunningTasks) RunningTasks.Add((int)task.AsyncState, task);
                    task.Start();
                }
                UpdateConsole();
                await Task.Delay(300); // wait before checking again
            }
            UpdateConsole();    // all done
        }

        static void UpdateConsole()
        {
            Console.Write(string.Format("\rwaiting: {0,3:##0}  running: {1,3:##0} ", WaitingTasks.Count, RunningTasks.Count));
        }

        // callback from finished worker
        static void WorkerDone(int id)
        {
            lock (RunningTasks) RunningTasks.Remove(id);
        }
    }

    internal class Worker
    {
        public delegate void DoneDelegate(int taskId);
        public static DoneDelegate Done { private get; set; }
        private static readonly Random Rnd = new Random();

        public async void DoWork(object id, CancellationToken token)
        {
            for (int i = 0; i < Rnd.Next(20); i++)
            {
                if (token.IsCancellationRequested) break;
                await Task.Delay(100);  // simulate work
            }
            Done((int)id);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

针对多个 Web 请求的最佳多线程方法 的相关文章

随机推荐

  • 从 Java 1.4 迁移到 Java 1.5+ 时避免 BigDecimal 的问题

    我最近将 Java 1 4 应用程序迁移到 Java 6 环境 不幸的是 我遇到了一个问题BigDecimal存储在Oracle数据库中 总而言之 当我尝试存储 7 65E 7 大十进制值 76 500 000 00 在数据库中 Oracl
  • 在 Java 中将常规日期转换为儒略日期,反之亦然

    我编写了一个简单的代码 将常规日期转换为儒略日期 对于需要相同转换的人来说 这是代码 public int convertToJulian String unformattedDate Unformatted Date ddmmyyyy i
  • 有没有办法直接从 C# 应用程序将文件写入 Azure Blob 存储?

    我正在尝试创建一个新的 C 控制台应用程序 直接从代码写入 blob 存储 我能够创建本地文件并将其上传到 blob 但要求是将内容直接写入 Blob 而不是创建文件并上传到 Blob 我无法实现这一点 我搜索了相关的网络资源 但找不到任何
  • 如何将 Symfony 发行版下载为 Zip 存档?

    我尝试下载 symfony 已有 2 个小时 但找不到可供下载的 zip 文件 我无法在我的网络上使用作曲家 这就是我想要 zip 的原因 我花了很多时间去 symfony 网站上的下载章节 但找不到任何 lts 版本的 zip 只有评估包
  • 获取蓝牙低功耗 (BLE) 设备通知的步骤是什么?

    我正在开发蓝牙低功耗 BLE 应用程序 我有一个测量体重的 BLE 设备 秤 我能够连接该设备 但我不知道如何从中读取数据 重量值 我想知道我的应用程序是否连接到任何 BLE 设备 那么要通过哪些步骤获得设备通知才能获取更新的数据 好的 以
  • HTML5表单验证-错误消息定制

    我有一个带有这样输入的表单
  • NSDictionary 过滤和排序

    我正在开发一个使用 JSON API 的应用程序 并且我正在使用 Objective C 框架的 JSON 将数据放入NSDictionary 字典是这样的 admitted
  • 如何通过R中的管道将输出发送到特定位置

    我正在编写一个小代码 比较两次并找到差异并以 HH MM SS 格式显示 library magrittr library lubridate s1 lt ymd hms Sys time s2 lt ymd hms Sys time 20
  • Windows Media Player COM 自动化可以在 VBS 中运行,但不能在 Python 中运行

    我尝试使用 Windows Media Player 通过 COM 播放音频文件 下面的代码在VBS中运行良好 Set wmp CreateObject WMPlayer OCX wmp settings autoStart True wm
  • 使用 STG 调用约定将 `foreign import prim` 与 C 函数一起使用

    我有一个简单的 C 例程 它接受四个字并返回四个字 gcc 可以对其进行优化并发出一些 GHC 不支持的 primops 我正在尝试对调用此过程的各种方法进行基准测试 但在尝试适应该技术时遇到了困难此处描述 http breaks for
  • 使用单一表单创建多个记录(非嵌套属性)

    在我的应用程序中 我有一个具有内容和作者属性的思想模型 我想用新的形式同时创造出多种想法 但这不是嵌套表单的情况 因为我没有使用任何关联的模型 请提出一些解决方案 提前致谢 您可以尝试使用以下解决方案 在您的查看文件中 Content Au
  • MVC 4 - 如何有条件地禁用此按钮?

    我想有条件地禁用此按钮 或隐藏它 如果Model BicycleSellerListingId不大于 0 不知道该怎么做 div using Html BeginForm Delete null new id Model BicycleSe
  • 如何将文件放入 Django 的固定装置中?

    我可以轻松地使用文件名填充 Django 固定装置中的 FileField 或 ImageField 字段 但该文件不存在 当我尝试测试我的应用程序时 它会失败 因为该文件不存在 如何在 Django 固定装置中正确填充 FileField
  • 自动实现的属性必须定义 get 和 set 访问器

    SQLCLR Visual Studio 2015 我是编写 CLR 代码的新手 编译 SQL CLR 函数时出现以下错误 我正在使用 Net 坐标库 https www doogal co uk dotnetcoords php 有问题的
  • 从字符串动态导入文件中的方法

    我有一个字符串 说 abc def ghi jkl myfile mymethod 如何动态导入mymethod 以下是我的做法 def get method from file full path if len full path 1 r
  • 将handlebars变量传递给客户端js文件

    我正在使用 Node js Express Handbars 构建一个应用程序 并正在寻找一种可以将车把数据从服务器传递到客户端 JavaScript 文件的方法 例如 server js var person name George ag
  • C 语言有哪些 XML API?

    它们都这么复杂吗 http msdn microsoft com en us library ms766497 VS 85 aspx http msdn microsoft com en us library ms766497 VS 85
  • 计算机多久会犯一次错误?

    我指的不是编程错误 这些错误实际上是由人类以某种方式造成的 而是在执行像将两个数字相加这样简单的操作时出现的错误 1 x 中预期出现错误的 x 范围是多少 就 CPU 而言 存在三种可能的错误来源 这些错误似乎在您的问题范围内 浮点舍入错误
  • 如何管理 ASP.NET 中触发事件的顺序?

    这个问题看似微不足道 但我没有通过谷歌找到答案 如果我在网络表单中有多个独立的控件 例如DropDownLists 和网格 我需要在另一个事件处理程序中使用来自一个事件处理程序的回发信息 因此我需要让它一次又一次地正确触发 我看到很多间接的
  • 针对多个 Web 请求的最佳多线程方法

    我想创建一个程序来爬行并检查我的网站是否有 http 错误和其他内容 我想使用多个线程来执行此操作 这些线程应该接受要抓取的 url 等参数 虽然我希望 X 线程处于活动状态 但仍有 Y 任务正在等待执行 现在我想知道执行此操作的最佳策略是