2011-02-02 104 views
2

刮掉一個包含大約250個表格部分的網頁。 使用華廷和WatinCSSSelectorsForeach循環需要很長時間才能打出

首先,我選擇帶有屬性的「width = 90%」的所有TD標籤:

var allMainTDs = browser.CssSelectAll("td[width=\"90%\"]"); 

然後我做一個foreach循環,堅持變種的內容到一個列表。 int在那裏檢查循環當前在哪個td標籤。

List<Element> eletd = new List<Element>(); 
int i = 0; 
foreach (Element td in allMainTDs) 
{ 
    eletd.Add(td); 
    i++; 
    Console.WriteLine(i);      
} 

它相當快地達到了第250個標記。但是,大約需要6分鐘(使用StopWatch對象計時)才能進入下一個語句。這裏發生了什麼?

+1

@MHTn什麼是`下一個語句` – msarchet 2011-02-02 16:27:10

+0

沒關係,此刻我有`int i = 0;`並且只是在那裏放置一個斷點。問題是需要AGES才能在foreach循環之後到達下一行代碼,在這種情況下是`int i = 0;`。 – MHTri 2011-02-02 16:28:33

+0

這很可能是CssSelectAll返回的集合的枚舉器的Dispose方法,它佔用了您的時間。你可以在探查器下運行它嗎? – 2011-02-02 16:32:24

回答

1

一個foreach循環大致相當於下面的代碼(不完全,但足夠接近):

IEnumerator<T> enumerator = enumerable.GetEnumerator(); 
try 
{ 
    while (enumerator.MoveNext()) 
    { 
     T element = enumerator.Current; 
     // here goes the body of the loop 
    } 
} 
finally 
{ 
    IDisposable disposable = enumerator as System.IDisposable; 
    if (disposable != null) disposable.Dispose(); 
} 

Th你描述的行爲指向這段代碼的清理部分。調用CssSelectAll調用結果的枚舉器可能有一個沉重的Dispose方法。你可以通過用類似上面的代碼替換你的循環來確認,並省略finally塊,或設置斷點來確認Dispose需要永久運行。

3

你可以試試這個:

var eletd = new List<Element>(allMainTDs); 
1

如果您在.NET 4.0和你的執行環境允許並行性,你可能應該嘗試

Prallel.ForEach(..); 
相關問題