递归函数MultiThreading一次执行一个任务

时间:2010-06-14 07:45:14

标签: c# asp.net multithreading recursion

我正在编写一个抓取网站的程序。爬网功能是递归功能,可能会花费更多时间来完成,因此我使用多线程来执行多个网站的爬网。  我究竟需要的是,在完成抓取一个网站之后,它会调用下一个网站(应该在Queqe中),而不是一次抓取多个网站。 我正在使用C#和ASP.NET。

4 个答案:

答案 0 :(得分:3)

执行此操作的标准做法是使用blocking queue。如果您使用的是.NET 4.0,那么您可以利用BlockingCollection类,否则您可以使用Stephen Toub的实现。

你要做的就是根据你的需要调整尽可能多的工作线程,然后让它们在队列中出现的无限循环中出现。你的主线程将列入项目。阻塞队列旨在等待/阻止出列操作,直到项目可用。

public class Program
{
  private static BlockingQueue<string> m_Queue = new BlockingQueue<string>();

  public static void Main()
  {
    var thread1 = new Thread(Process);
    var thread2 = new Thread(Process);
    thread1.Start();
    thread2.Start();
    while (true)
    {
      string url = GetNextUrl();
      m_Queue.Enqueue(url);
    }
  }

  public static void Process()
  {
    while (true)
    {
      string url = m_Queue.Dequeue();
      // Do whatever with the url here.
    }
  }
}

答案 1 :(得分:2)

对于网页抓取工具,我通常不会想到积极的想法......

您想使用threadpool

 ThreadPool.QueueUserWorkItem(new WaitCallback(CrawlSite), (object)s);

您只需将工作负载“推送”到队列中,然后让线程池管理它。

答案 2 :(得分:1)

我必须说 - 我不是线程专家,而且我的C#非常生疏 - 但考虑到要求,我会建议这样的事情:

  1. 为网站定义队列。
  2. 使用Crawler个主题定义池。
  3. 主进程遍历网站队列并检索站点地址。
  4. 从池中检索可用线程 - 为其分配网站地址并允许其开始运行。在线程对象中设置一个指示器,它应该等待所有后续线程完成(因此您将不会继续到下一个站点)。
  5. 一旦所有线程结束 - 主线程(在步骤#4中启动)将结束并返回主进程的主循环以继续到下一个网站。
  6. Crawler行为应该是这样的:

        
    1. 调查当前地址的内容
    2.   
    3. 检索当前级别下的层次结构
    4.   
    5. 对于站点树当前节点的每个子节点 - 从池中拉出一个新的crawler线程并使用子节点的地址在后台运行它
    6.   
    7. 如果池为空,请等待线程可用。
    8.   
    9. 如果线程被标记为等待 - 等待所有其他线程完成
    10. 我认为这里存在一些挑战 - 但作为一般流程,我相信它可以做到。

答案 3 :(得分:0)

将所有网址放入队列中,并在每次完成上一个网址时弹出一个网址。

您还可以将递归链接放入队列中,以便更好地控制您一次执行的下载次数。

您可以设置X个工作线程,这些线程都会从队列中获取一个url,以便一次处理更多。但是这样你就可以自己节制它。

您可以在.Net中使用ConcurrentQueue<T>来获取可以使用的线程安全队列。