创意联盟

 找回密码
 注册

用新浪微博连接

一步搞定

QQ登录

只需一步,快速开始

查看: 700|回复: 0

如何用C#语言构造蜘蛛程序(2) [复制链接]

Rank: 80Rank: 80Rank: 80Rank: 80Rank: 80

发表于 2008-4-24 22:33:15 |显示全部楼层
  四、任务完成了吗?
  利用多个线程同时下载文件有效地提高了性能,但也带来了线程管理方面的问题。其中最复杂的一个问题是:蜘蛛程序何时才算完成了工作?在这里我们要借助一个专用的类Done来判断。
  首先有必要说明一下"完成工作"的具体含义。只有当系统中不存在等待下载的URL,而且所有工作线程都已经结束其处理工作时,蜘蛛程序的工作才算完成。也就是说,完成工作意味着已经没有等待下载和正在下载的URL。
  Done类提供了一个WaitDone方法,它的功能是一直等待,直到Done对象检测到蜘蛛程序已完成工作。下面是WaitDone方法的代码。
public void WaitDone()
{
Monitor.Enter(this);
while ( m_activeThreads>0 )
{
Monitor.Wait(this);
}
Monitor.Exit(this);
}


  WaitDone方法将一直等待,直到不再有活动的线程。但必须注意的是,下载开始的最初阶段也没有任何活动的线程,所以很容易造成蜘蛛程序一开始就立即停止的现象。为解决这个问题,我们还需要另一个方法WaitBegin来等待蜘蛛程序进入"正式的"工作阶段。一般的调用次序是:先调用WaitBegin,再接着调用WaitDone,WaitDone将等待蜘蛛程序完成工作。下面是WaitBegin的代码:
public void WaitBegin()
{
Monitor.Enter(this);
while ( !m_started )
{
Monitor.Wait(this);
}
Monitor.Exit(this);
}


  WaitBegin方法将一直等待,直到m_started标记被设置。m_started标记是由WorkerBegin方法设置的。工作线程在开始处理各个URL之时,会调用WorkerBegin;处理结束时调用WorkerEnd。WorkerBegin和WorkerEnd这两个方法帮助Done对象确定当前的工作状态。下面是WorkerBegin方法的代码:
public void WorkerBegin()
{
Monitor.Enter(this);
m_activeThreads++;
m_started = true;
Monitor.Pulse(this);
Monitor.Exit(this);
}


  WorkerBegin方法首先增加当前活动线程的数量,接着设置m_started标记,最后调用Pulse方法以通知(可能存在的)等待工作线程启动的线程。如前所述,可能等待Done对象的方法是WaitBegin方法。每处理完一个URL,WorkerEnd方法会被调用:
public void WorkerEnd()
{
Monitor.Enter(this);
m_activeThreads--;
Monitor.Pulse(this);
Monitor.Exit(this);
}


  WorkerEnd方法减小m_activeThreads活动线程计数器,调用Pulse释放可能在等待Done对象的线程--如前所述,可能在等待Done对象的方法是WaitDone方法。
  结束语:本文介绍了开发Internet蜘蛛程序的基础知识,下面提供的源代码将帮助你进一步深入理解本文的主题。这里提供的代码非常灵活,你可以方便地将它用于自己的程序。
您需要登录后才可以回帖 登录 | 注册

Archiver|意盟 ( 闽ICP备06022703号 )

GMT+8, 2012-5-20 04:17 , Processed in 0.043192 second(s), 17 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部