[Twisted-Python] Creating a COM object in a thread
Hugh Emberson
hugh.emberson at gmail.com
Wed Jun 30 20:02:22 MDT 2010
The way I do this is I isolate all the COM stuff in a separate thread
from thread that runs my reactor.
This thread starts by calling:
pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
it then creates the COM object and runs an event loop something like this:
while keepRunning:
n = MsgWaitForMultipleObjects(handles, False, timeout, QS_ALLINPUT)
if n == WAIT_OBJECT_0 + nHandles:
# There is a win32 message waiting.
if pythoncom.PumpWaitingMessages():
keepRunning = False
I send messages to the thread by putting them in a queue and setting
an event. The messages cause methods to be called on the COM object.
I send the results of the COM methods back to the reactor thread using
reactor.callFromThread().
It's a bit of effort to do this, but it works really well. It's been
in production for several years and I've never had a problem with it.
Hope this helps,
Hugh
On Tue, Jun 29, 2010 at 10:43 AM, Don Dwiggins <ddwiggins at advpubtech.com> wrote:
>
> I need to create a COM object in a Windows application, and call it.
> Since the call will take some time to execute, I wrap it in a deferToThread.
>
> I've found that, when I create the object inline, it works. However,
> when I defer it, it hangs up in the win32com.client.Dispatch call. I've
> tried several things, including digging into the guts of Dispatch -- the
> hangup occurs during the creation of the object.
>
> I've discussed this with Mark Hammond, who suggests one lead:
>
> "The Windows message loop is used by the COM marshalling process. IIRC,
> the first thread to initialize COM in a process is the thread in which
> single-threaded objects will always end up being called in. If a
> different thread creates the object, COM uses Windows messages to
> marshall all calls back to that main thread. IOW, your second thread
> makes a call - even to create the object - which results in that thread
> sending a windows message to the main thread to act on the request.
>
> What this probably means in practice is that twisted needs to use a
> reactor which calls MsgWaitForMultipleObjects() and runs a message loop
> when the function detects a new message is in the queue. I'm not sure
> if there is an existing reactor which does this."
>
> I'm posting this on the off chance that someone else has wandered into
> this corner of Windows arcana, and has come up with something useful.
>
> I'm about to give up on doing this "inside" the twisted app, and running
> it in a separate app that I'll call from the thread.
>
> TIA,
> --
> Don Dwiggins
> Advanced Publishing Technology
>
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
More information about the Twisted-Python
mailing list