我正在使用 CherryPy 开发一个 Web 应用程序,它需要通过 COM 访问一些应用程序。
现在我为每个请求创建一个新的应用程序实例,这意味着每个请求等待应用程序启动 3 秒,实际作业等待 0.01 秒。
我想启动每个 COM 应用程序一次并使其保持活动状态并在以下请求中重复使用它几秒钟,因为大多数时候它被 5-10 个 ajax 请求突发使用,然后几个小时没有任何请求。
是否可以在 CherryPy 应用程序的所有线程之间共享 COM 对象?
下面是一些实验的总结,展示了它现在如何处理每个请求以及它如何不能跨线程工作。
以下代码成功启动和停止 Excel:
>>> import pythoncom, win32com.client
>>> def start():
global xl
xl = win32com.client.Dispatch('Excel.Application')
>>> def stop():
global xl
xl.quit()
xl = None
>>> start()
>>> stop()
但是下面的代码启动 Excel 并在 3 秒后关闭它。
>>> import pythoncom, win32com.client, threading, time
>>> def start():
global xl
pythoncom.CoInitialize()
xl = win32com.client.Dispatch('Excel.Application')
time.sleep(3)
>>> threading.Thread(target=start).start()
我添加了对 CoInitialize()
的调用,否则 xl
对象将不起作用(参见 这篇文章)。
我添加了 3 秒暂停,所以我可以在任务管理器上看到 EXCEL.EXE 进程启动并存活 3 秒。
为什么它在启动它的线程结束后就死了?
我检查了 CoInitialize()
的文档,但我不明白是否有可能让它在多线程环境中工作。
原文由 stenci 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果你想在多线程中使用 win32com,你需要做更多的工作,因为
COMObject
不能直接传递给线程。您需要使用CoMarshalInterThreadInterfaceInStream()
和CoGetInterfaceAndReleaseStream()
在线程之间传递实例:有关详细信息,请参阅: https ://mail.python.org/pipermail/python-win32/2008-June/007788.html