2013-03-22 56 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