Concurrent 函数
适用于: 画布应用 模型驱动应用
并发计算多个公式。
说明
Concurrent 函数允许在同一属性中指定的多个公式同时计算,前提是这些公式有连接器或 Dataverse 调用。 通常情况下,多个公式由 ;(分号)运算符串联计算,此运算符按顺序计算每个公式。 使用 Concurrent 函数,应用将同时计算属性中的所有公式,即使是使用 ; 运算符之后。 这一并发将帮助用户减少等待计算结果的时间,结果不会改变。
在应用的 OnStart 属性中,使用 Concurrent 在应用加载数据时提高性能。 如果必须等到前一个调用完成才能启动数据调用,则应用必须等待所有请求时间之和。 如果数据调用都同时启动,应用只需等待最长请求的时间。 Web 浏览器通常通过同时执行网络调用提高性能。
不能预测 Concurrent 函数中的公式开始和结束求值的顺序。 Concurrent 函数中的公式不应包含对同一 Concurrent 函数中其他公式的依赖项,如果尝试这么做,Power Apps 会显示错误。 在其中,可以安全接受对 Concurrent 函数之外公式的依赖项,因为它们会在 Concurrent 函数开始之前完成。 Concurrent 函数后的公式可以安全接受对其中公式的依赖项:它们都会在 Concurrent 函数完成并转到链中下一个公式(如果使用 ; 运算符)前完成。 如果要调用有副作用的函数或服务方法,请注意细微的顺序依赖关系。
可在 Concurrent 的参数内使用 ; 运算符串联公式。 例如 Concurrent( Set( a, 1 ); Set( b, a+1 ), Set( x, 2 ); Set( y, x+2 ) ) 将同时计算 Set( a, 1 ); Set( b, a+1 ) 和 Set( x, 2 ); Set( y, x+2 )。 在本例中,公式内的依赖项可正常运行:a 将在 b 前设置,x 将在 y 前设置。
根据应用运行于的设备或浏览器,实际可能只有少量的公式会同时求值。 Concurrent 使用可用功能,并且在评估完所有公式之前不会完成。
如果(在高级设置中)启用公式级错误管理,Concurrent 将返回参数命令中遇到的第一个错误;否则返回空白。 如果所有公式都成功,则返回 true。 如果一个公式失败,则该公式的其余部分将会停止,但其他公式将继续计算。
只能在行为公式中使用 Concurrent。
语法
并发( 公式 1, 公式 2 [,...])
- Formulas(公式) –必需。 要同时计算的公式。 必须提供至少两个公式。
示例
更快地加载数据
创建一个应用,并从 Microsoft Dataverse、SQL Server 或 SharePoint 添加四个数据源。
此示例使用来自 SQL Azure 上的示例 Adventure Works 数据库的四个表。 创建数据库后,请使用完全限定的服务器名称(例如 srvname.database.windows.net)从 Power Apps 连接到它:
添加 Button 控件,并将其 OnSelect 属性设置为以下公式:
ClearCollect( Product, '[SalesLT].[Product]' ); ClearCollect( Customer, '[SalesLT].[Customer]' ); ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' ); ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' )
在 Microsoft Edge 或 Google Chrome 中,打开开发人员工具,以便在应用运行时监视网络流量。
(可选)打开网络限制,增强这一比较的效果。
按住 Alt 键,选择按钮,然后观察网络流量。
工具会显示按顺序执行的四个请求,与此示例类似。 示例中删除了实际时间,因为它们将有很大差异。 图标显示,每个调用都在上一个调用完成后启动:
保存、关闭并重新打开应用。
Power Apps 会缓存数据,因此再次选择该按钮不一定会产生四个新请求。 每次要测试性能时,都要关闭并重新打开应用。 如果打开了网络限制,最好将其关闭,直到准备好进行另一个测试。
添加第二个 Button 控件,并将其 OnSelect 属性设置为以下公式:
Concurrent( ClearCollect( Product, '[SalesLT].[Product]' ), ClearCollect( Customer, '[SalesLT].[Customer]' ), ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' ), ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' ) )
请注意,对第一个按钮添加了相同 ClearCollect 调用,但这一次,它们封装在 Concurrent 函数中,由逗号分隔。
清除浏览器中的网络监视器。
如果在此前使用了网络限制,请将其重新打开。
按住 Alt 键,选择第二个按钮,然后观察网络流量。
工具会显示同时执行的四个请求,与此示例类似。 再一次,示例中删除了实际时间,因为它们将有很大差异。 图表显示,所有调用在大致相同的时间开始,并不等待上一个调用完成:
这些图表基于相同的刻度。 通过使用 Concurrent,将完成这些操作所用的时间总量减少了一半。
保存、关闭并重新打开应用。
争用条件
Microsoft 将 Translator 服务连接到您的应用。
添加一个 Text input 控件,然后将其重命名为 TextInput1(如果它具有不同名称)。
添加 Button 控件,并将其 OnSelect 属性设置为以下公式:
Set( StartTime, Value( Now() ) ); Concurrent( Set( FRTrans, MicrosoftTranslator.Translate( TextInput1.Text, "fr" ) ); Set( FRTransTime, Value( Now() ) ), Set( DETrans, MicrosoftTranslator.Translate( TextInput1.Text, "de" ) ); Set( DETransTime, Value( Now() ) ) ); Collect( Results, { Input: TextInput1.Text, French: FRTrans, FrenchTime: FRTransTime - StartTime, German: DETrans, GermanTime: DETransTime - StartTime, FrenchFaster: FRTransTime < DETransTime } )
添加数据表控件,然后将其 Items 属性设置为 Results。
在右窗格的属性选项卡上,选择编辑字段以打开字段窗格。
在字段列表中,选中每个字段的复选框,以在数据表中显示它们。
(可选)将 Input 字段拖动到列表顶部,并将 FrenchFaster 字段拖动到列表底部。
在 Text input 控件中,键入或粘贴要翻译的短语。
按住 Alt 键,多次选择按钮以填充该表。
时间以毫秒为单位显示。
在某些情况下,法语翻译比德语翻译快,有时则相反。 二者同时开始,但由于各种原因(包括网络延迟和服务器端处理),二者相继返回。
如果应用依赖于一种语言的翻译率先结束,将出现争用条件。 幸运的是,Power Apps 会标志它能检测到的大多数执行时间依赖项。