从C ++切换到C#时,为什么从BHO内部调用IHTMLElement2.getBoundingClientRect会慢几倍?

问题描述

我正在尝试创建用于遍历HTML页面DOM的BHO的各​​种选项。一个实现使用C#,并且在ApartmentModel设置为Both的情况下在注册表中注册。它是这样的:

  1. 检索IWebbrowser2.Document
  2. 从文档对象获取IDocumentSelector接口
  3. 调用IDocumentSelector.querySelectorAll("*")会产生一个IHTMLDOMChildrenCollection参考
  4. 获取IHTMLDOMChildrenCollection.length
  5. 0..length范围(for(int index = 0; index < totalCount; index++))内运行循环,
  6. 内部循环迭代使用IHTMLDOMChildrenCollection.item()获取每个集合项,
  7. 将收集项引用投射到IHTMLElement2
  8. 获取IHTMLElement2.getClientBoundingRect()

,并且效果很好,在200-300毫秒内遍历了大约1500个元素的页面(循环持续时间是通过在循环前后读取DateTime.UtcNow并从读数差中获取TotalMilliseconds来测量的)。

使用Visual C ++和ATL完成的另一种实现。它的功能与C#版本基本相同。 CComQIPtr用于代替强制类型转换。循环是相同的。还已将ApartmentModel设置为Both进行注册

C ++实现在40-60毫秒内遍历同一页面DOM。时间是通过在循环之前和之后读取GetTickCount()并得出差值来测量的。

然后,我从内部循环迭代中排除了步骤8-获得了项并从中获得了IHTMLElement2,但是没有调用getClientBoundingRect()。更改之后,两种实现都几乎同时在40-50毫秒的时间内运行。

这看起来很奇怪。为什么只有getClientBoundingRect()会受到影响?它有什么特别之处以至于放慢了速度?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)