2011-02-02 93 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(..); 
相关问题