COM:从其他线程调用导致崩溃,如何使其在同一线程上运行?
我正在做一个 BHO(IE 的扩展),它接收其他线程上的事件。 当我从另一个线程访问 DOM 时,IE 崩溃了。 是否可以使 DOM 从与主 BHO 线程相同的线程访问,这样它就不会崩溃?
这似乎是一个一般的COM多线程问题,我不太明白。
I am doing a BHO (extension for IE) that receives events on other thread. When I access the DOM from that other thread, IE crashes. Is it possible to make the DOM accessed from the same thread as the main BHO thread so that it does not crash?
It seems like a general COM multithreading problem, which I don't understand much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
考虑使用 CoMarshalInterface 或 CoMarshalInterThreadInterfaceInStream
这些将为您提供线程安全的 STA COM 对象的包装接口。
Look into using CoMarshalInterface or CoMarshalInterThreadInterfaceInStream
These will give you a wrapped interface to an STA COM object that is thread safe.
我对 IE 扩展了解不多,但听起来有些 COM 对象需要标记为单线程单元,以便 COM 运行时系统确保它在最初调用它的同一线程上运行。 如果您无法更改其他对象,您可能可以通过标记为 STA 的单独 COM 对象将调用路由到 DOM,以达到相同的效果。 希望这会有所帮助...我对 COM 多线程了解一点,但对 IE 扩展了解不多。
I don't know much about IE extensions, but it sounds like some COM object needs to be marked a Single Threaded Apartment, so that the COM runtime system ensures that it is run on the same thread which called it initially. If you can't alter the other object, you could probably route your calls to the DOM through a separate COM object marked as STA to achieve the same effect. Hope this helps... I know a bit about COM multithreading, but not much about IE extensions.
啊,有趣有趣有趣的 COM 多线程。
ah, fun fun fun multithreading with COM.
Gerald's answer looks right if you want to transfer an interface pointer from one thread to another exactly once. I've found that the GIT (global interface table) is a big help for this kind of thing if you're in a multithreaded system... basically you don't keep around interface pointers but rather DWORD cookies used by the GIT to get an appropriately-marshaled interface pointer for whatever thread you are using it. (you have to register the object in question with the GIT first, and unregister it later when you are done or your object is finished)
不过要小心。 性能可能会成为一个严重的问题。
如果您只是想了解 BHO,则可以使用 STA 使 ::SetSite() 实现对象像单线程一样运行(这允许您让其他线程将 BHO 的指针从 GlobalInterfaceTable 中拉出)正如 @JasonS 提到的,
如果您正在做的事情预计会成为产品的一部分,我强烈建议您非常仔细地重新考虑尽可能使用 MTA 并自己处理并发和线程安全问题,在这种情况下您只需要这样做。确保与 BHO COM 对象互操作的线程本身是针对 COM 进行初始化的。
例如,如果您想监视网站的传入/传出数据以查找事物(危险的或敏感的),那么您不想这样做。强制所有这些线程进入 STA 对象的喉咙,因为以 Yahoo 为例,将启动超过 30 个请求,并且您的 BHO 将开始锁定 IE。
Be careful though. Performance can become a serious issue.
If you're just playing around to learn about BHOs, you can use the STA to make your ::SetSite() implementing object operate as if it were single threaded (this allows you to let other threads pull your BHO's pointer out of the GlobalInterfaceTable as @JasonS mentions.
If you're doing something that is expected to be part of a product I highly recommend you very carefully reconsider going MTA everywhere you can and handling the concurrency and thread safety issues yourself. In this case you would only need to ensure that the threads inter-operating with your BHO COM object, were themselves, initialized for COM.
For example, if you want to monitor incoming/outgoing data of website looking for things (either dangerous or sensitive) - then you do NOT want to force all of those threads down the throat of an STA object because, using Yahoo as an example, more than 30 requests will launch and your BHO will start locking up IE.