c# - 如何在多线程时传递不同的实例?

标签 c# multithreading

我正在构建一个抓取工具。我的目标是启动 X 个浏览器(其中 X 是线程数),然后通过将列表分成 X 个部分来继续抓取每个浏览器的 URL 列表。

我决定使用 3 个线程(3 个浏览器)和 10 个 URL 列表。

问题:如何像这样在浏览器之间分隔每个任务:

  1. Browser1 抓取列表中从 0 到 3 的项目

  2. Browser2 将列表中的项目从 4 抓取到 7

  3. Browser3 将列表中的项目从 8 抓取到 10

所有浏览器都应该同时抓取传递的 URL 列表。

我已经有了这个 BlockingCollection:

BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();

public Multithreading(int workerCount)
{
        // Create and start a separate Task for each consumer:
        for (int i = 0; i < workerCount; i++)
            Task.Factory.StartNew(Consume);
}

public void Dispose() { _taskQ.CompleteAdding(); }

public void EnqueueTask(Action action) { _taskQ.Add(action); }

void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called. 
foreach (Action action in _taskQ.GetConsumingEnumerable())
            action();     // Perform task.
}
public int ItemsCount()
{
        return _taskQ.Count;
}

可以这样使用:

Multithreading multithread = new Multithreading(3); //3 threads
foreach(string url in urlList){

    multithread.EnqueueTask(new Action(() => 
    {
         startScraping(browser1); //or browser2 or browser3
    }));
}

我需要在抓取之前创建浏览器实例,因为我不想在每个线程都启动一个新浏览器。

最佳答案

考虑到 Henk Holtermans 的评论,您可能想要最大速度,即让浏览器尽可能忙碌,使用这个:

private static void StartScraping(int id, IEnumerable<Uri> urls)
{
    // Construct browser here
    foreach (Uri url in urls)
    {
        // Use browser to process url here
        Console.WriteLine("Browser {0} is processing url {1}", id, url);
    }
}

主要是:

    int nrWorkers = 3;
    int nrUrls = 10;
    BlockingCollection<Uri> taskQ = new BlockingCollection<Uri>();
    foreach (int i in Enumerable.Range(0, nrWorkers))
    {
        Task.Run(() => StartScraping(i, taskQ.GetConsumingEnumerable()));
    }
    foreach (int i in Enumerable.Range(0, nrUrls))
    {
        taskQ.Add(new Uri(String.Format("http://Url{0}", i)));
    }
    taskQ.CompleteAdding();

关于c# - 如何在多线程时传递不同的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25348803/

相关文章:

c# - 在 CaSTLe Windsor 中,我可以注册一个接口(interface)组件并获得实现的代理吗?

python - Python Tkinter程序崩溃时忘记了()

c++ - 有什么方法可以强制openmp获得所需的线程数?

Java 线程异常终止并出现消息为 null 的异常。

c# - Xamarin 社区工具包 MediaPlayer 自动播放不起作用?

c# - Xamarin 表单 XAML : How can I inherit properties from another XAML file like ResourceDictionaries?

c# - 防止所有机器人访问页面

c# - C# 中的非托管 dll 函数字节 * 参数返回

c# - 将图像转换为灰度并行循环

java - 如何等待所有线程执行完毕?