スレッドに関する問題の解釈

このトピックでは、Microsoft UI オートメーション クライアント実装の一般的なスレッド シナリオについて説明し、クライアントがスレッドを誤って使用した場合に発生する可能性のある問題を回避する方法について説明します。

このトピックは、次のセクションで構成されています。

UI オートメーションと UI スレッド

UI オートメーションが Windows メッセージを使用する方法により、クライアント アプリケーションが UI スレッド上で独自の UI と対話しようとすると競合が発生する可能性があります。 これらの競合が発生すると、パフォーマンスが著しく低下したり、アプリケーションが応答を停止したりする可能性もあります。

クライアント アプリケーションが、独自の UI を含むデスクトップ上のすべての要素と対話することを目的としている場合は、すべての UI オートメーション呼び出しを別のスレッドから行う必要があります。 これには、たとえば IUIAutomationTreeWalker または IUIAutomationElement::FindAll メソッドを使用したり、コントロール パターンを使用したりして、要素を特定することが含まれます。 このスレッドはウィンドウを所有してはならず、またコンポーネント オブジェクト モデル (COM) マルチスレッド アパートメント (MTA) モデル スレッド (COINIT_MULTITHREADED フラグを指定して CoInitializeEx を呼び出し、COM を初期化するスレッド) である必要があります。

イベント ハンドラーは常に非 UI スレッドで呼び出されるため、UI オートメーション イベント ハンドラーで UI オートメーションの呼び出しを行っても安全です。 ただし、クライアント アプリケーション UI から発生する可能性のあるイベントをサブスクライブする場合は、非 UI スレッド (MTA スレッドでもある必要があります) で IUIAutomation::AddAutomationEventHandler または関連メソッドを呼び出す必要があります。 同じスレッドにあるイベント ハンドラーを削除します。

UI オートメーション クライアントでは、イベント ハンドラーを追加または削除するために複数のスレッドを使用しないでください。 同じクライアント プロセスで、あるイベント ハンドラーを追加中または削除中に別のイベント ハンドラーを追加または削除すると、予期しない動作が発生する可能性があります。

イベント ハンドラーのスレッド モデル

UI オートメーション クライアントは、イベント ハンドラーを実装するスレッドに COM MTA スレッド モデルを使用する必要があります。 シングルスレッド アパートメント (STA) モデルを使用すると、クライアントがスレッドからイベント ハンドラーを削除できなくなるなどの問題が発生する可能性があります。

64 ビット Windows での COM アパートメント アフィニティ

COM 仕様に従い、リモート オブジェクトの有効期間は、オブジェクトを作成するために CoCreateInstance 関数が呼び出されるアパートメントの有効期間によって制御されます。 元のアパートメントがシャットダウンすると、リモート オブジェクトも解放されます。

UI オートメーション クライアントの場合、この COM の動作は、32 ビット要素によって使用されるリモート 32/64 ヘルパー (UIAutomationCore.dll によって作成) の有効期間が、要素を作成したスレッドのアパートメント有効期間によって制御されることを意味する場合があります。 UI オートメーション クライアントが要素を別のスレッドにマーシャリングすると、元のアパートメントがシャットダウンしたときに要素が無効になる可能性があります。 UI オートメーション クライアントは、マーシャリングされたオートメーション要素の使用中にエラーをキャッチして、これらの問題を適切に処理する必要があります。

64 ビット要素を持つ 32 ビット UI オートメーション クライアントでも同じ問題が発生する可能性があります。

概念:

UI オートメーション要素の取得

UI オートメーション イベントのサブスクライブ

UI オートメーション イベントの概要

その他のリソース

OLE スレッド モデルの説明と動作