在 UI 自动化客户端中缓存

更新:2007 年 11 月

本主题介绍 UI 自动化属性和控件模式的缓存。 

在 UI 自动化中,缓存意味着预获取数据。然后,无需进一步的跨进程通信即可访问数据。UI 自动化客户端应用程序通常使用缓存来批量检索属性和控件模式。然后,根据需要从缓存中检索信息。应用程序会定期更新缓存,通常在发生表明 用户界面 (UI) 中的内容发生更改的事件时进行更新。

对于具有服务器端 UI 自动化提供程序的 Windows Presentation Foundation (WPF) 控件和自定义控件,缓存的优势非常突出。在访问客户端提供程序(比如 Win32 控件的默认提供程序)时,其优势稍小一些。 

当应用程序激活 CacheRequest 然后使用返回 AutomationElement 的任何方法或属性时,就会进行缓存;例如,FindFirstFindAllTreeWalker 类的方法例外;只有在将 CacheRequest 指定为参数(例如,TreeWalker.GetFirstChild(AutomationElement, CacheRequest))时,才会进行缓存。

如果在 CacheRequest 处于活动状态时订阅事件,也会进行缓存。作为事件来源传递到事件处理程序的 AutomationElement 包含由原始 CacheRequest 指定的缓存属性和模式。在订阅事件后对 CacheRequest 进行的任何更改没有影响。

可以对元素的 UI 自动化属性和控件模式进行缓存。

本主题包括下列各节。

  • 缓存选项
  • 激活 CacheRequest
  • 检索缓存的属性
  • 检索缓存的控件模式
  • 检索缓存的子项和父项
  • 更新缓存
  • 相关主题

缓存选项

CacheRequest 指定以下缓存选项。

要缓存的属性

可以通过在激活请求之前为每个属性调用 Add(AutomationProperty) 来指定要缓存的属性。

要缓存的控件模式

可以通过在激活请求之前为每个模式调用 Add(AutomationPattern) 来指定要缓存的控件模式。在缓存模式时,不会自动缓存模式的属性;您必须通过使用 CacheRequest.Add 来指定要缓存的属性。

缓存的范围和筛选

可以通过在激活请求之前设置 CacheRequest.TreeScope 属性来指定要缓存其属性和模式的元素。范围与请求处于活动状态时检索的元素有关。例如,如果只设置 Children 然后检索 AutomationElement,则会缓存该元素的子项的属性和模式,但不会缓存该元素本身的属性和模式。若要确保对检索的元素本身进行缓存,您必须在 TreeScope 属性中包括 Element。无法将范围设置为 ParentAncestors。不过,在缓存了子元素后,就可以缓存父元素;请参见本主题中的“检索缓存的子项和父项”。

缓存的范围还受 CacheRequest.TreeFilter 属性的影响。默认情况下,只会对出现在 UI 自动化树的控件视图中的元素执行缓存。但是,可以更改此属性以将缓存应用于所有元素,或者只应用于出现在内容视图中的元素。

元素引用的强度

在检索 AutomationElement 时,默认情况下您可以访问该元素的所有属性和模式,包括那些未缓存的属性和模式。不过,为了提高效率,您可以通过将 CacheRequestAutomationElementMode 属性设置为 None 来指定元素引用只引用缓存的数据。在这种情况下,您无法访问所检索元素的任何未缓存属性和模式。这意味着,您无法通过 GetCurrentPropertyValue 或者 AutomationElement 的 Current 属性或任何控件模式访问任何属性;也无法通过使用 GetCurrentPatternTryGetCurrentPattern 检索模式。在缓存的模式上,您可以调用检索数组属性的方法(如 SelectionPattern.SelectionPatternInformation.GetSelection),但不能调用对控件执行操作的任何方法(如 InvokePattern.Invoke)。

可能无需完全引用对象的应用程序的一个示例是屏幕阅读器,它将预提取窗口中元素的 NameControlType 属性,但不需要 AutomationElement 对象本身。

激活 CacheRequest

只有当在 CacheRequest 对于当前线程处于活动状态的情况下检索 AutomationElement 对象时,才会执行缓存。有两种方法可激活 CacheRequest

通常的方法是调用 Activate。此方法返回实现 IDisposable 的对象。只要 IDisposable 对象存在,请求就将保持活动状态。控制对象生存期最简单的方法是将调用包括在 using (C#) 或 Using (Visual Basic) 块中。这样即使引发异常也能确保请求从堆栈中弹出。

另一种方法(在希望嵌套缓存请求时十分有用)是调用 Push。此方法将请求放在堆栈上,并激活请求。在 Pop 从堆栈中移除请求之前,请求将保持活动状态。如果将另一个请求推入堆栈,该请求将暂时变为非活动状态;只有堆栈顶部的请求才会处于活动状态。

检索缓存的属性

您可以通过以下方法和属性检索元素的缓存属性。

如果请求的属性不在缓存中,将会引发异常。

CachedCurrent 一样,都以结构成员的方式公开各项属性。不过,您无需检索此结构;您可以直接访问各项属性。例如,可以从 element.Cached.Name 中获取 Name 属性,其中 element 是 AutomationElement

检索缓存的控件模式

您可以通过以下方法检索元素的缓存控件模式。

如果模式不在缓存中,GetCachedPattern 将引发异常,并且 TryGetCachedPattern 将返回 false。

您可以通过使用模式对象的 Cached 属性来检索控件模式的缓存属性。您还可以通过 Current 属性检索当前值,但只有当检索 AutomationElement 时未指定 None 的情况下才能这样做。(默认值为 Full,并且此值允许访问当前值。)

检索缓存的子项和父项

如果检索 AutomationElement 并通过请求的 TreeScope 属性请求对该元素的子项进行缓存,随后将可以从所检索元素的 CachedChildren 属性中获取子元素。

如果 Element 包括在缓存请求的范围中,随后将可以从任何子元素的 CachedParent 属性中获取请求的根元素。

说明:

您无法缓存请求根元素的父项或上级。

更新缓存

缓存只有在 UI 中没有任何更改时才有效。应用程序负责更新缓存,通常是为了响应事件。

如果在 CacheRequest 处于活动状态时订阅事件,则无论您何时调用事件处理程序委托,都会获得一个使用更新的缓存作为事件源的 AutomationElement。您也可以通过调用 GetUpdatedCache 来更新元素的缓存信息。您可以传入原始 CacheRequest 来更新以前缓存的所有信息。

更新缓存不会更改任何现有 AutomationElement 引用的属性。

请参见

任务

在 UI 自动化中使用缓存

FetchTimer 示例

概念

客户端的 UI 自动化事件