Цикл Foreach выходит из строя очень долго - PullRequest
2 голосов
/ 02 февраля 2011

Очистка веб-страницы, содержащей около 250 разделов таблицы.Использование WatiN и WatinCSSSelectors

Сначала я выбираю все теги td с атрибутом 'width = 90%':

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

Затем я создаю цикл foreach, помещая содержимое переменной в список,Int предназначен для проверки того, в каком тэге находится тэг в данный момент.

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

Он достигает 250-го тэга довольно быстро.Но тогда для перехода к следующему оператору требуется около 6 минут (при времени с объектом StopWatch).Что здесь происходит?

Ответы [ 3 ]

3 голосов
/ 02 февраля 2011

Вы можете попробовать это:

var eletd = new List<Element>(allMainTDs);
1 голос
/ 02 февраля 2011
Цикл

A 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();
}

Поведение, которое вы описываете, указывает на часть очистки этого кода. Возможно, что перечислитель для результата вызова CssSelectAll имеет тяжелый метод Dispose. Вы можете подтвердить это, заменив цикл на что-то вроде приведенного выше кода, и опустите блок finally или установите точки останова, чтобы подтвердить, что Dispose работает вечно.

1 голос
/ 02 февраля 2011

Если вы используете .net 4.0 и ваша среда исполнения допускает параллелизм, вам, возможно, стоит попробовать

  Prallel.ForEach(..);
...