Grundlegendes zu Threadingproblemen
In diesem Thema werden allgemeine Threadingszenarien für Microsoft Benutzeroberflächenautomatisierung-Clientimplementierungen beschrieben und erläutert, wie Probleme vermieden werden können, die auftreten können, wenn ein Client Threading falsch verwendet.
Dieses Thema enthält folgende Abschnitte:
- Benutzeroberflächenautomatisierung und den UI-Thread
- Threadingmodell für Ereignishandler
- COM Apartment Affinity on 64-bit Windows
- Zugehörige Themen
Benutzeroberflächenautomatisierung und den UI-Thread
Aufgrund der Art und Weise, Benutzeroberflächenautomatisierung Windows verwendet, können Konflikte auftreten, wenn eine Clientanwendung versucht, mit ihrer eigenen Benutzeroberfläche im UI-Thread zu interagieren. Diese Konflikte können zu einer sehr langsamen Leistung führen oder sogar dazu führen, dass die Anwendung nicht mehr reagiert.
Wenn Ihre Clientanwendung mit allen Elementen auf dem Desktop interagieren soll, einschließlich ihrer eigenen Benutzeroberfläche, sollten Sie alle Benutzeroberflächenautomatisierung von einem separaten Thread aus aufrufen. Dies schließt das Suchen von Elementen ein, z. B. mithilfe von IUIAutomationTreeWalker oder der IUIAutomationElement::FindAll-Methode und mithilfe von Steuerelementmustern. Dieser Thread sollte keine Fenster besitzen und ein MTA-Modellthread (Multithreaded Apartment) von Component Object Model (COM) sein (ein Thread, der COM initialisiert, indem CoInitializeEx mit dem COINIT _ MULTITHREADED-Flag aufgerufen wird).
Es ist sicher, Benutzeroberflächenautomatisierung in einem Benutzeroberflächenautomatisierung-Ereignishandler zu erstellen, da der Ereignishandler immer für einen Nicht-UI-Thread aufgerufen wird. Wenn Sie jedoch Ereignisse abonnieren, die möglicherweise von der Benutzeroberfläche Ihrer Clientanwendung stammen, müssen Sie IUIAutomation::AddAutomationEventHandleroder eine zugehörige Methode in einem Nicht-UI-Thread aufrufen (der auch ein MTA-Thread sein sollte). Entfernen Sie Ereignishandler im gleichen Thread.
Ein Benutzeroberflächenautomatisierung-Client sollte nicht mehrere Threads verwenden, um Ereignishandler hinzuzufügen oder zu entfernen. Unerwartetes Verhalten kann dazu führen, dass ein Ereignishandler hinzugefügt oder entfernt wird, während ein anderer im gleichen Clientprozess hinzugefügt oder entfernt wird.
Threadingmodell für Ereignishandler
Ein Benutzeroberflächenautomatisierung-Client sollte das COM MTA-Threadingmodell für Threads verwenden, die Ereignishandler implementieren. Die Verwendung des Sta-Modells (Singlethreaded Apartment) kann Probleme verursachen, z. B. das Entfernen von Ereignishandlern aus dem Thread durch Clients verhindern.
COM Apartment Affinity on 64-bit Windows
Gemäß der COM-Spezifikation wird die Lebensdauer eines Remoteobjekts durch die Lebensdauer des Apartments bestimmt, in dem die CoCreateInstance-Funktion aufgerufen wird, um das Objekt zu erstellen. Wenn das ursprüngliche Apartment heruntergefahren wird, wird auch das Remoteobjekt freigegeben.
Bei Benutzeroberflächenautomatisierung-Clients kann dieses COM-Verhalten bedeuten, dass die Lebensdauer des remoten 32/64-Hilfsers (erstellt von UIAutomationCore.dll), das von einem 32-Bit-Element verwendet wird, von der Lebensdauer des Apartments des Threads bestimmt wird, der das Element erstellt hat. Wenn der Benutzeroberflächenautomatisierung Client das Element an einen anderen Thread marshallt, kann das Element ungültig werden, wenn das ursprüngliche Apartment heruntergefahren wird. Der Benutzeroberflächenautomatisierung-Client sollte diese Probleme ordnungsgemäß behandeln, indem er Fehler abfing, während gemarshallte Automatisierungselemente verwendet werden.
Das gleiche Problem kann bei einem 32-Bit-Benutzeroberflächenautomatisierung-Client auftreten, der 64-Bit-Elemente enthält.