2013-03-22 60 views
1

我想使用httpwebrequest访问Web服务器,并从给定范围的页面中获取数千条记录。每击中一个网页就会获取15条记录,并且网络服务器上几乎有8到10000个页面。这意味着服务器总共有120000次点击!如果使用单个进程轻松完成,任务可能非常耗时。因此,多线程是想到的即时解决方案。使用多个线程来实现从Web服务器进行高效搜索

目前,我创建了一个用于搜索目的的工作者类,该工作者类将产生5个子工作者(线程)来在给定范围内进行搜索。但是,由于我的线程新手能力,我无法使其工作,因为我无法同步并使它们一起工作。我知道在.NET代表,行动,事件,而是使其与螺纹越来越confusing..This工作是我使用的代码:

public void Start() 
{ 
    this.totalRangePerThread = ((this.endRange - this.startRange)/this.subWorkerThreads.Length); 
    for (int i = 0; i < this.subWorkerThreads.Length; ++i) 
    { 
     //theThreads[counter] = new Thread(new ThreadStart(MethodName)); 
     this.subWorkerThreads[i] = new Thread(() => searchItem(this.startRange, this.totalRangePerThread)); 
     //this.subWorkerThreads[i].Start(); 
     this.startRange = this.startRange + this.totalRangePerThread; 
    } 

    for (int threadIndex = 0; threadIndex < this.subWorkerThreads.Length; ++threadIndex) 
     this.subWorkerThreads[threadIndex].Start(); 
} 

的searchItem方法:

public void searchItem(int start, int pagesToSearchPerThread) 
{ 
    for (int count = 0; count < pagesToSearchPerThread; ++count) 
    { 
    //searching routine here 
    } 
} 

问题存在于线程的共享变量之间,任何人都可以引导我如何使它成为一个线程安全的过程?

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2013-03-22 18:46:42

+0

@JohnSaunders下次会小心..谢谢 – faizanjehangir 2013-03-22 18:49:57

+0

@faizanjehangir - 您是否考虑过使用提供FTS功能的数据库?如果您正在手动执行操作,这对DDOS非常敏感。 – tjameson 2013-03-22 18:53:12

回答

1

您面临的真正问题是Thread构造函数中的labmda表达式正在捕获外部变量(startRange)。要解决这个问题的方法之一是使变量的副本,如:了解更多信息

for (int i = 0; i < this.subWorkerThreads.Length; ++i) 
{ 
    var copy = startRange; 
    this.subWorkerThreads[i] = new Thread(() => searchItem(copy, this.totalRangePerThread)); 
    this.startRange = this.startRange + this.totalRangePerThread; 
} 

上创建和启动线程,请参见乔阿尔巴哈利的优秀ebook(有也是在捕捉变量位进一步下跌的一段)。如果您想了解关闭,请参阅this问题。

+0

感谢您的信息..我会更多地了解它。 – faizanjehangir 2013-03-22 19:37:44

1

第一个答案是这些线程并不需要做太多工作来共享变量(假设我正确理解了你)。他们有一些共享的输入变量(例如目标Web服务器),但这些变量是线程安全的,因为它们没有被更改。计划是他们将建立一个数据库或其中包含他们检索的记录的数据库。你应该没问题,只要让五个填充自己的输入档案,然后一旦所有的子工作线程完成,就把它们合并到一个单独的线程中。如果你用来存储数据的体系结构使得这些数据变得昂贵,那么你打算存储多少计划以及你计划存储什么内容变得相关,那么,也许你可以分享一下那些是?

+0

变量被分享的意思是变量'start'结束在最后一个线程中具有更新的值,它会覆盖之前的那些... – faizanjehangir 2013-03-22 18:59:42

+0

所以不要覆盖它。让每个线程创建一个新的局部变量,并保持输入参数不变。我个人认为,默认情况下单独保留输入参数是一般良好的编码习惯。 – 2013-03-22 19:01:09

+0

但是,每次启动时线程都不会共享相同的函数searchItem?覆盖或使用其他变量? – faizanjehangir 2013-03-22 19:07:30