Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用多线程从web服务器实现高效搜索_C#_Multithreading_Thread Safety - Fatal编程技术网

C# 使用多线程从web服务器实现高效搜索

C# 使用多线程从web服务器实现高效搜索,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,我想使用httpwebrequest访问web服务器,并从给定范围的页面中获取数千条记录。对一个网页的每次点击都会获取15条记录,而该Web服务器上几乎有8到10000页。这意味着总共有120000次点击服务器!如果用一个简单的进程来完成,任务可能会非常耗时。因此,多线程是立即想到的解决方案 目前,我已经创建了一个用于搜索的worker类,该worker类将产生5个子worker(线程)在给定范围内进行搜索。但是,由于我在线程方面的新手能力,我无法使它工作,因为我在同步和使它们一起工作方面遇到了

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

目前,我已经创建了一个用于搜索的worker类,该worker类将产生5个子worker(线程)在给定范围内进行搜索。但是,由于我在线程方面的新手能力,我无法使它工作,因为我在同步和使它们一起工作方面遇到了困难。我知道.NET中的委托、操作和事件,但让它们与线程一起工作会让人感到困惑..这是我正在使用的代码:

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();
}
public void Start()
{
this.totalRangePerThread=((this.endRange-this.startRange)/this.subWorkerThreads.Length);
for(int i=0;isearchItem(this.startRange,this.totalRangePerThread));
//this.subWorkerThreads[i].Start();
this.startRange=this.startRange+this.totalRangePerThread;
}
对于(int-threadIndex=0;threadIndex
searchItem方法:

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

线程的共享变量之间存在问题,有人能指导我如何使其成为线程安全过程吗?

第一个答案是,这些线程实际上不需要那么多工作来共享变量(假设我正确理解您)。它们有一些共享的输入变量(例如,目标web服务器),但这些变量是线程安全的,因为它们没有被更改。计划是,他们将建立一个数据库或类似的数据库,其中包含他们检索到的记录。您可以让这五个线程中的每一个都填充它们自己的输入存档,然后在完成所有子工作线程后将它们合并到一个线程中。如果你用来存储数据的架构让它变得昂贵。。。那么,您计划存储多少以及您计划存储什么就变得相关了,也许您可以分享这些内容?

您所面临的真正问题是
线程中的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;
}
for(int i=0;isearchItem(复制,this.totalRangePerThread));
this.startRange=this.startRange+this.totalRangePerThread;
}

有关创建和启动线程的更多信息,请参阅Joe Albahari的优秀文章(下面还有一节介绍捕获的变量)。如果您想了解闭包,请参阅问题。

我已编辑了您的标题。请看“”,其中的共识是“不,他们不应该”。@JohnSaunders下次会小心。。thanks@faizanjehangir-您是否考虑过使用提供FTS功能的数据库?如果您手动操作,这很容易受到DDOS的影响。如果您不控制该web服务器(即,它属于其他人),他们可能会阻止您以过快的速度攻击它们。他们会认为你在进行DDOS攻击。如果你控制了服务器(从而控制了数据),你就不能用另一种方式获得你需要的信息吗?(如数据转储等)共享变量的可能重复是因为变量
start
在最后一个线程中具有更新的值,它会覆盖以前的值…所以不要覆盖它。让每个线程创建一个新的局部变量,并保持输入参数不变。我个人认为默认情况下只留下输入参数是一个很好的编码实践。但是,这些线程在每次启动时都不会共享相同的函数<代码>搜索项< /代码>吗?覆盖或使用其他变量?如果您在searchitem函数中定义了局部变量,那么它的作用域就是该函数的执行范围。searchItem函数确实是由所有线程执行的,但每次执行都是特定于线程的——就好像是以串行方式而不是并行方式运行它一样。