UI オートメーション クライアントにおけるキャッシュ
Note
このドキュメントは、System.Windows.Automation 名前空間で定義されているマネージド UI オートメーション クラスを使用する .NET Framework 開発者を対象としています。 UI オートメーションの最新情報については、Windows Automation API の「UI オートメーション」を参照してください。
このトピックでは、UI オートメーションのプロパティとコントロール パターンのキャッシュについて説明します。
UI オートメーションでは、キャッシングはデータのプリフェッチを意味します。 そのデータには、さらにプロセス間通信を行わずにアクセスできます。 キャッシュは通常、UI オートメーション クライアント アプリケーションによって使用され、プロパティとコントロール パターンを一括で取得します。 それから、必要に応じて情報がキャッシュから取得されます。 アプリケーションはキャッシュを定期的に更新します。通常は、ユーザー インターフェイス (UI) で何かが変更されたことを示すイベントへの応答として更新を行います。
キャッシュの効果は、サーバー側 UI オートメーション プロバイダーを持つ Windows Presentation Foundation (WPF) コントロールとカスタム コントロールで最も顕著に表れます。 Win32 コントロールの既定のプロバイダーなど、クライアント側プロバイダーにアクセスするときは、メリットが小さくなります。
キャッシュはアプリケーションが CacheRequest をアクティブにしたときに発生し、 AutomationElementや FindFirstなど、 FindAllを返すメソッドやプロパティを使用します。 TreeWalker クラスのメソッドは例外で、 CacheRequest がパラメーターとして指定された場合 (たとえば、 TreeWalker.GetFirstChild(AutomationElement, CacheRequest)) にのみ、キャッシュが行われます。
また、キャッシュは、 CacheRequest がアクティブなときにイベントにサブスクライブする場合にも発生します。 イベントのソースとしてイベント ハンドラーに渡された AutomationElement には、元の CacheRequestによって指定されているキャッシュされたプロパティとパターンが含まれています。 イベントにサブスクライブした後で CacheRequest に加えられた変更が、影響を与えることはありません。
要素の UI オートメーションのプロパティとコントロール パターンはキャッシュできます。
キャッシュのオプション
CacheRequest はキャッシュ用の次のオプションを指定します。
キャッシュするプロパティ
要求をアクティブ化する前に、各プロパティの Add(AutomationProperty) を呼び出して、キャッシュするプロパティを指定できます。
キャッシュするコントロール パターン
要求をアクティブ化する前に、各パターンの Add(AutomationPattern) を呼び出して、キャッシュするコントロール パターンを指定できます。 パターンがキャッシュされるとき、そのプロパティは自動的にはキャッシュされません。 CacheRequest.Addを使用して、キャッシュするプロパティを指定する必要があります。
キャッシュのスコープとフィルター処理
要求をアクティブ化する前に CacheRequest.TreeScope プロパティを設定し、キャッシュするプロパティやパターンを持つ要素を指定できます。 スコープは、要求がアクティブな間に取得される要素を基準としています。 たとえば、 Childrenのみを設定し、 AutomationElementを取得する場合に、要素の子のプロパティとパターンはキャッシュされますが、要素自体のプロパティとパターンはキャッシュされません。 取得される要素自体についてキャッシュが行われるようにするには、 Element プロパティに TreeScope を含める必要があります。 スコープを Parent または Ancestorsに設定することはできません。 ただし、子要素がキャッシュされるときに親要素もキャッシュできます。 詳細については、「キャッシュされた子と親の取得」を参照してください。
キャッシュの範囲は、 CacheRequest.TreeFilter プロパティによっても影響を受けます。 既定では、キャッシュは UI オートメーション ツリーのコントロール ビューに表示される要素にのみ実行されます。 ただし、キャッシュをすべての要素に適用したり、コンテンツ ビューに表示される要素にのみ適用したりするように、このプロパティを変更することができます。
要素の参照の強度
AutomationElementを取得するときは、既定では、キャッシュされていないものも含め、その要素のすべてのプロパティとパターンにアクセスできます。 ただし、作業効率を向上するために、 AutomationElementMode の CacheRequest プロパティを Noneに設定して、要素への参照がキャッシュされたデータのみを参照するよう指定できます。 この場合、取得された要素のキャッシュされていないプロパティとパターンには、いずれもアクセスできません。 つまり、 GetCurrentPropertyValue を通してプロパティにアクセスしたり、 Current
の AutomationElement プロパティやコントロール パターンにアクセスすることはできません。また、 GetCurrentPattern や TryGetCurrentPatternを使用してパターンを取得することもできません。 キャッシュされたパターンでは、 SelectionPattern.SelectionPatternInformation.GetSelectionなどの配列のプロパティを取得するメソッドを呼び出すことができますが、 InvokePattern.Invokeなどのコントロール上でアクションを実行するものは呼び出すことができません。
オブジェクトへの完全参照を必要としない可能性があるアプリケーションの例として、スクリーン リーダーがあります。これは、ウィンドウ内の要素の Name プロパティと ControlType プロパティをプリフェッチしても、 AutomationElement オブジェクト自体は必要としません。
CacheRequest のアクティブ化
AutomationElement が現在のスレッドに対してアクティブである間に CacheRequest オブジェクトが取得された場合にのみ、キャッシュが実行されます。 CacheRequestをアクティブ化するには、2 つの方法があります。
通常の方法では、 Activateを呼び出します。 このメソッドは、 IDisposableを実装するオブジェクトを返します。 要求は、 IDisposable オブジェクトが存在する限りアクティブなままです。 オブジェクトの有効期間を制御する最も簡単な方法は、using
(C#) または Using
(Visual Basic) のブロック内に呼び出しを埋め込むことです。 これにより、例外が発生した場合でも、スタックから要求がポップされます。
キャッシュ要求を入れ子にする場合に有用な別の方法は、 Pushを呼び出すことです。 この方法では、スタック上に要求が配置され、アクティブ化されます。 Popによってスタックから削除されるまで、要求はアクティブなままです。 別の要求がスタックにプッシュされた場合、要求は一時的に非アクティブになります。スタックの最上位の要求のみがアクティブになります。
キャッシュされたプロパティの取得
要素のキャッシュされたプロパティを取得するには、次のメソッドとプロパティを使用します。
要求されたプロパティがキャッシュ内にない場合、例外が発生します。
Cachedと同様、 Currentは構造体のメンバーとして、個々のプロパティを公開します。 ただし、この構造体を取得する必要はありません。個々のプロパティに直接アクセスすることができます。 たとえば、 Name プロパティは element.Cached.Name
から取得できます。ここで、 element
は AutomationElementです。
キャッシュされたコントロール パターンの取得
要素のキャッシュされたコントロール パターンを取得するには、次のメソッドを使用します。
パターンがキャッシュ内にない場合、 GetCachedPattern で例外が発生し、 TryGetCachedPattern が false
を返します。
パターン オブジェクトの Cached
プロパティを使用して、コントロール パターンのキャッシュされたプロパティを取得できます。 Current
プロパティを通じて現在の値を取得することもできますが、 None が取得されたときに AutomationElement が指定されていない場合に限ります。 (Full は既定値であり、これにより現在の値へのアクセスが許可されます。)
キャッシュされた子と親の取得
AutomationElement を取得し、要求の TreeScope プロパティを通じてその要素の子のキャッシュを要求すると、その後は、取得した要素の CachedChildren プロパティから子要素を取得することが可能になります。
Element がキャッシュ要求のスコープに含まれていた場合には、要求のルート要素は、その後、任意の子要素の CachedParent プロパティから利用できます。
Note
要求のルート要素の親または先祖をキャッシュすることはできません。
キャッシュの更新
UI で何も変更されない限り、キャッシュは有効です。 キャッシュの更新は、通常はイベントへの応答として、アプリケーションが行います。
CacheRequest がアクティブな間にイベントにサブスクライブすると、イベント ハンドラーのデリゲートが呼び出されるたびに、イベントのソースとしてキャッシュが更新された AutomationElement を取得します。 また、 GetUpdatedCacheを呼び出して、要素のキャッシュされた情報を更新することもできます。 元の CacheRequest を渡して、以前にキャッシュされたすべての情報を更新できます。
キャッシュを更新しても、既存の AutomationElement の参照のプロパティはいずれも変更されません。