Pracuję nad aplikacją internetową z CherryPy, która potrzebuje dostępu do kilku aplikacji za pośrednictwem COM.Używanie win32com z wielowątkowością
W tej chwili tworzę nowe wystąpienie aplikacji dla każdego żądania, co oznacza, że każde żądanie czeka 3 sekundy na uruchomienie aplikacji i 0,01 dla rzeczywistej pracy.
Chciałbym uruchomić każdą aplikację COM jeden raz i zachować ją przy życiu i ponownie używać przez kilka sekund w następujących żądaniach, ponieważ przez większość czasu jest używana przez serię 5-10 zapytań ajax, a następnie nic przez wiele godzin .
Czy można udostępniać abuzję COM we wszystkich wątkach aplikacji CherryPy?
Oto podsumowanie kilku eksperymentów pokazujących, jak działa teraz każde żądanie i jak nie działa w wątkach.
Poniższy kod z powodzeniem uruchamia i zatrzymuje 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()
ale następujący kod rozpoczyna Excel i zamyka go po 3 sekundach.
>>> 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()
dodałem wywołanie CoInitialize()
inaczej przedmiot xl
nie będzie działać (patrz this post).
Dodałem 3-sekundową przerwę, dzięki czemu mogłem zobaczyć na menedżerze zadań, że rozpoczyna się proces EXCEL.EXE i jest on aktywny przez 3 sekundy.
Dlaczego umiera po zakończeniu wątku, który ją rozpoczął?
Sprawdziłem dokumentację CoInitialize()
, ale nie mogłem zrozumieć, czy można go uruchomić w środowisku wielowątkowym.
Sztuką może zainicjować wątek dla wielowątkowym apartamentu (aka, free-gwintowany) używać. Wypróbuj [CoInitializeEx] (http://docs.activestate.com/activepython/2.5/pywin32/pythoncom__CoInitializeEx_meth.html) za pomocą opcji 'COINIT_APARTMENTTHREADED'. – tdelaney