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