python,COM和多线程问题 [英] python, COM and multithreading issue

查看:94
本文介绍了python,COM和多线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从分派IE的单独线程中查看IE的DOM,对于某些属性,我会遇到不支持此类接口"错误.我设法将问题简化为以下脚本:

I'm trying to take a look at IE's DOM from a separate thread that dispatched IE, and for some properties I'm getting a "no such interface supported" error. I managed to reduce the problem to this script:

import threading, time

import pythoncom
from win32com.client import Dispatch, gencache
gencache.EnsureModule('{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}', 0, 4, 0) # MSHTML

def main():
    pythoncom.CoInitializeEx(0)
    ie = Dispatch('InternetExplorer.Application')
    ie.Visible = True
    ie.Navigate('http://www.Rhodia-ecommerce.com/')
    while ie.Busy:
        time.sleep(1)

    def printframes():
        pythoncom.CoInitializeEx(0)
        document = ie.Document
        frames = document.getElementsByTagName(u'frame')
        for frame in frames:
            obj = frame.contentWindow

    thr = threading.Thread(target=printframes)
    thr.start()
    thr.join()

if __name__ == '__main__':
    thr = threading.Thread(target=main)
    thr.start()
    thr.join()

一切都很好,直到 frame.contentWindow .然后ba:

Everything is fine until the frame.contentWindow. Then bam:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\python22\lib\threading.py", line 414, in __bootstrap
    self.run()
  File "C:\python22\lib\threading.py", line 402, in run
    apply(self.__target, self.__args, self.__kwargs)
  File "testie.py", line 42, in printframes
    obj = frame.contentWindow
  File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 455, in __getattr__
    return self._ApplyTypes_(*args)
  File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 446, in _ApplyTypes_
    return self._get_good_object_(
com_error: (-2147467262, 'No such interface supported', None, None)

有任何提示吗?

推荐答案

正确的答案是手动封送东西.这不是解决方法,而是您应该在此处执行的操作.不过,您不必使用单元线程.

The correct answer is to marshal stuff by hand. That's not a workaround it is what you are supposed to do here. You shouldn't have to use apartment threading though.

您初始化为多线程单元-告诉COM 可以在任何线程上调用您的接口.它不允许允许您在任何线程上调用其他接口,或从COM提供的编组接口中解雇.那只会偶然"起作用-例如如果您正在调用的对象恰好是一个进程内MTA对象,则无所谓.

You initialised as multithreaded apartment - that tells COM that it can call your interfaces on any thread. It does not allow you to call other interfaces on any thread, or excuse you from marshalling interfaces provided by COM. That will only work "by accident" - E.g. if the object you are calling happens to be an in-process MTA object, it won't matter.

CoMarshalInterThreadInterfaceInStream / CoGetInterfaceAndReleaseStream 做生意.

这样做的原因是对象可以提供自己的代理,它们可以是自由线程,也可以不是自由线程.(或者确实提供自定义编组).您必须封送他们,以告诉他们它们在线程之间移动.如果代理是自由线程的,则可能会返回相同的指针.

The reason for this is that objects can provide their own proxies, which may or may not be free-threaded. (Or indeed provide custom marshalling). You have to marshal them to tell them they are moving between threads. If the proxy is free threaded, you may get the same pointer back.

这篇关于python,COM和多线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆