Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Foreach循环需要很长时间才能脱离_C#_Foreach_Watin_Enumeration - Fatal编程技术网

C# Foreach循环需要很长时间才能脱离

C# Foreach循环需要很长时间才能脱离,c#,foreach,watin,enumeration,C#,Foreach,Watin,Enumeration,抓取一个网页,包含大约250个表格分区。 使用WatiN和WATINCSS选择器 首先,我选择属性为“width=90%”的所有td标记: var allMainTDs = browser.CssSelectAll("td[width=\"90%\"]"); 然后我创建一个foreach循环,将var的内容粘贴到一个列表中。int用于检查循环当前的td标记 List<Element> eletd = new List<Element>(); int i = 0; for

抓取一个网页,包含大约250个表格分区。 使用WatiN和WATINCSS选择器

首先,我选择属性为“width=90%”的所有td标记:

var allMainTDs = browser.CssSelectAll("td[width=\"90%\"]");
然后我创建一个foreach循环,将var的内容粘贴到一个列表中。int用于检查循环当前的td标记

List<Element> eletd = new List<Element>();
int i = 0;
foreach (Element td in allMainTDs)
{
    eletd.Add(td);
    i++;
    Console.WriteLine(i);                    
}
List eletd=new List();
int i=0;
foreach(所有维护TDS中的元素td)
{
增加(td);
i++;
控制台写入线(i);
}
它相当快地到达第250个标签。但接下来要花大约6分钟(用秒表对象计时)才能进入下一个语句。这里发生了什么?

您可以尝试以下方法:

var eletd = new List<Element>(allMainTDs);
var eletd=新列表(allMainTDs);

如果您在.net 4.0下运行,并且您的执行环境允许并行,您可能需要尝试

  Prallel.ForEach(..);

一个
foreach
循环大致相当于以下代码(不完全相同,但足够接近):

IEnumerator enumerator=enumerable.GetEnumerator();
尝试
{
while(枚举数.MoveNext())
{
T元素=枚举数。当前;
//这是循环的主体
}
}
最后
{
IDisposable disposable=枚举器作为System.IDisposable;
if(disposable!=null)Dispose.Dispose();
}

您描述的行为指向此代码的清理部分。
CssSelectAll
调用结果的枚举数可能有一个重Dispose方法。您可以通过使用类似上述代码的内容替换循环来确认这一点,并省略finally块,或设置断点以确认
Dispose
将永远运行。

@MHTn下一个语句是什么没关系,目前我有
int I=0并在那里放置一个断点。问题是到达foreach循环后的下一行代码需要很长时间,在这种情况下
inti=0。这很可能是CssSelectAll返回的集合枚举数的Dispose方法占用您的时间。你能在探查器下运行这个吗?你有没有尝试过在遇到延迟时中断,以查看你在堆栈中的位置?听起来好像有什么东西阻碍了第250个元素的枚举。@Martinho Fernandes-我刚刚下载了ANTS profiler试用版,但我不确定要看什么。目前,foreach循环占总时间成本的84%。然而我发现调用Watin方法作为CSSSelector的一部分似乎是这个耗时过程中最大的一部分。。。也许我会坚持旧的循环,如果语句@贾斯汀·摩根——我点击了暂停,它只是用绿色突出显示了foreach循环(特别是“in”字)。不确定这意味着什么。列表构造函数也将遍历所有maintds。我不知道这会有什么帮助,但它确实使代码更简单。感谢这个快捷方式,它与foreach循环具有相同的效果和时间消耗,但它读起来更简单!这听起来很简单,但我需要列表数据才能继续。谢谢你提醒我这一点。@那么另一个思路是为生成所有maintd的源代码实现自定义迭代器,你必须自己进行DOM遍历,但可能值得一试。谢谢你的代码。在找到第250个表div后,它实际上会在(enumerator.MoveNext())
期间挂起。在通常的6分钟后,我们到达最后一个街区,处理一次,然后我可以继续。ANTS Profiler显示堆栈上的最后一个调用是
WatiN.Core.Native.InternetExplorer.ieeeElement+c_udisplayClassc.b_ub()
@MHTri:oh,所以需要很长时间才能找到更多的tds。除非文档太大(我的意思是,太大了),否则我会将此作为一个可能的bug报告给WatiN团队。或者它可能与IE有关……后来我开始尝试另一种解决方案,但感谢您的帮助!
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();
}