2011-02-02 7 views
2

約250の表区切りを含むWebページをスクラップします。 は、私は属性を持つすべてのtdタグを選択WatiNとWatinCSSSelectorsForeachループが抜け出すには非常に時間がかかります

ファーストを使用して「幅= 90%」:

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

それから私は、リストにVARの内容を貼り、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

+0

私は 'int i = 0;'を持っていて、そこにブレークポイントを置くだけで問題ありません。問題は、foreachループの後で次のコード行に進むためにはAGESが必要であるということです(この場合はint i = 0; ')。 – MHTri

+0

CssSelectAllによって返されたコレクションの列挙子のDisposeメソッドは、時間を浪費する可能性があります。これをプロファイラの下で実行できますか? –

答えて

1

を試してみてください次のコード(正確ではないが十分に近い):

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が永遠に実行されることを確認することで、これを確認できます。

+0

このコードをありがとう。 250番目のテーブルdivの後に 'while(enumerator.MoveNext())'に実際にハングします。通常の6分後、我々は最終的にブロックに到着し、処分は一度起こり、次に進むことができます。 ANTS Profilerは、スタック上の最後の呼び出しが「WatiN.Core.Native.InternetExplorer.IEEElement + <> c__DisplayClassc。 b__b()」であることを示しています。 – MHTri

+0

@MHTri:ああ、これ以上ないことを理解するまでに時間がかかる見つけられるtds。文書が巨大でない限り(私は大きすぎる)、これをWatiNチームに報告したいと思います。それとも、IEに関連するものかもしれません... –

+0

私はその後、別の解決策を試してみましたが、手伝ってくれてありがとう! – MHTri

3

あなたはこの試みることができる:あなたの.NET 4.0の下で、あなたの実行環境は、並列処理を可能にした場合、あなたがかもしれ

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

リストのコンストラクタはallMainTDを繰り返し処理します。これがどのように役立つかはわかりませんが、コードをもっと簡単にしてくれます。 –

+0

このショートカットをありがとう、それはforeachループと同じ効果と時間消費を持っていますが、より簡単に読むことができます! – MHTri

1

foreachループはほぼ同等である

Prallel.ForEach(..); 
+0

これはきちんと聞こえますが、これ以上進める前にリストデータが必要です。しかし、私の注意をそれに持ってくれてありがとう。 – MHTri

+0

@別の考え方では、allMainTDを生成するソースのカスタムイテレータを実装することに目を向け、独自のDOMトラバーサルを行う必要がありますが、試してみる価値があります。 – dexter