【发布时间】:2010-10-21 05:58:50
【问题描述】:
我有一个正在用 C# 开发的 IE BHO。它应该等待用户做一些事情,联系我们的服务器并下载一些数据,然后用结果改变当前加载网页的 DOM。
我遇到了一些与 COM 划分和线程规则相关的看似无法克服的问题——也就是说,我似乎无法访问当前线程之外的 IE DOMDocument,而且我想不出任何方法来运行某些东西异步完成,不锁定 IE。
我的第一次尝试是让后台服务器通信以事件驱动的方式完成它的工作:我的程序将从 mshtml 事件(例如,BeforeNaviagate2 或 DocumentComplete)中启动通信,并从一个服务器通信对象完成工作时触发的单独事件处理程序。
该技术在我拼凑在一起的快速模拟器中运行良好(只是一个带有 WebBrowser 控件的简单应用程序),但在 IE 中它会抛出 COM 异常,因为我试图通过单独的线程更改页面 DOM。
所以我尝试将所有内容都保存在同一个函数中,并让我的代码等待服务器通信对象使用 while 循环完成其工作,如下所示:
int waited = 0;
while (!OurServerCommRequest.ready) {
System.Threading.Thread.Sleep(1);
Application.DoEvents();
waited++;
if (waited > constants.TIMEOUT_OURSERVER_REQUEST) {
log.wL("Timed out");
}
}
这种方法的问题是当代码保留在原始线程中时,它会与它触发的 IE 进程同步执行(在 IE8 中,它是每个选项卡一个进程 - 就像 Google Chrome 一样 - 似乎)......因此锁定 IE 界面,直到我的服务器通信完成。
最初我想在 URL 可用时立即开始处理(通过 NavigationComplete2 事件),但我发现如果我的服务器通信在用户页面加载之前完成,等待
标记变为可用也会锁定 IE -- 在我的代码等待 HTML 正文时将其放入无限循环,而页面被阻止更新自身执行上述循环。我曾考虑将所有这些都移到实际用户的页面 javascript 中,但似乎这样做我打开了一罐蠕虫来解决 XSS 安全问题。
所以...我的问题是这样的:是否可以在 C# IE BHO 中异步运行代码,同时仍然能够操作用户的页面 DOM?我问了一些朋友,大多数人告诉我这不太可能。我还是 COM 和 C# 的新手,来自 C/VB.net/JS/AS。
谢谢!
-汤姆
【问题讨论】:
-
汤姆,你有没有让这个工作?如果是这样,您有代码示例吗?我正在解决类似的问题,但找不到保持异步的方法。作为一种解决方法,我做了你上面描述的(while 循环),但这是不可接受的。谢谢。
-
自从我从事这个项目以来已经有一段时间了,但我相信通过将服务器请求旋转到另一个线程然后在它改变 DOM 之前切换到主 IE 线程来解决这个问题.这避免了违规并将我们的代码注入到页面 DOM 中而不会中断用户。可以在此处找到弹跳线程的详细信息:stackoverflow.com/questions/2367718/…
标签: multithreading internet-explorer com asynchronous bho