win32com und Threads

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Red Rooster
User
Beiträge: 12
Registriert: Donnerstag 8. November 2012, 13:30

Ich habe ein Problem mit threading und win32com. Ich habe eine kleine Python-Funktion geschrieben, die einwandfrei läuft, solange man diese aus einer einfachen Applikation (ohne threading) aufruft.

Code: Alles auswählen

def add(x, y):
    access = win32com.client.Dispatch('Access.Application')
    access.OpenCurrentDatabase('c:\\PKBerichteBibo_9012_6.ACCDB')
    retval = access.Run('bgaAddiere', x, y)
    access.CloseCurrentDatabase()
    return retval[0]
Sobald man diese Funktion allerdings aus einem Thread heraus aufrufen möchte, bringt die win32com einen "Ausnahmefehler" und bricht den access.Run-Befehl ab. Was kann man tun, damit ich diese Funktion auch aus einem Thread heraus aufrufen kann?
lunar

@Red Rooster COM implementiert ein eigenes Threading-Modell. Grob gesagt unterteilt COM Threads in "Appartements", je nachdem ob ein COM-Objekt threadsicher ist oder nicht. Dahinter steht der Versuch, Threadsicherheit beim Zugriff auf COM-Objekte möglichst zu erzwingen.

Dieses Threading-Modell muss für jeden Thread des Prozesses mit CoInitializeEx initialisiert werden. Ich nehme an, dass Dir die Ausnahme sagt, dass diese Funktion nicht aufgerufen wurde. Wo sich diese Funktion in pywin32 befindet, kann ich Dir nicht sagen. Durchsuche die Hilfe-Datei von pywin32.

Diese Funktion musst Du im neuen Thread aufrufen, bevor Du irgendein COM-Objekte erzeugst oder verwendest. Ferner darfst Du ein COM-Objekt nur und ausschließlich in dem Thread verwenden, in dem es erzeugt wurde (es sei denn, dass COM-Objekt läuft in einem MTA-Thread, dann darf jeder andere MTA-Thread auch darauf zugreifen, doch das ist in Deinem Fall wohl egal).

Im Allgemeinen ist Threading in Verbindung mit COM diffizil, und ich würde raten, nach Möglichkeit COM nur im Hauptthread der Anwendung zu verwenden.
Antworten