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

语法

Concurrent( Formula1, Formula2 [, ...] )

  • Formula(s) – 必需。 要同时计算的公式。 必须提供至少两个公式。

示例

更快地加载数据

  1. 创建一个应用,并从 Microsoft Dataverse、SQL Server 或 SharePoint 添加四个数据源。

    此示例使用来自 SQL Azure 上的示例 Adventure Works 数据库的四个表。 创建数据库后,请使用完全限定的服务器名称(例如 srvname.database.windows.net)从 Power Apps 连接到它:

    连接到 Azure 中的 Adventure Works 数据库。

  2. 添加 Button 控件,并将其 OnSelect 属性设置为以下公式:

    ClearCollect( Product, '[SalesLT].[Product]' );
    ClearCollect( Customer, '[SalesLT].[Customer]' );
    ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' );
    ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' )
    
  3. Microsoft EdgeGoogle Chrome 中,打开开发人员工具,以便在应用运行时监视网络流量。

  4. (可选)打开网络限制,增强这一比较的效果。

  5. 按住 Alt 键,选择按钮,然后观察网络流量。

    工具会显示按顺序执行的四个请求,与此示例类似。 示例中删除了实际时间,因为它们将有很大差异。 图标显示,每个调用都在上一个调用完成后启动:

    四个网络请求的时间图表,其中每个请求都在上一个完成后启动,从而占用整个时间跨度。

  6. 保存、关闭并重新打开应用。

    Power Apps 会缓存数据,因此再次选择该按钮不一定会产生四个新请求。 每次要测试性能时,都要关闭并重新打开应用。 如果打开了网络限制,最好将其关闭,直到准备好进行另一个测试。

  7. 添加第二个 Button 控件,并将其 OnSelect 属性设置为以下公式:

    Concurrent(
        ClearCollect( Product, '[SalesLT].[Product]' ),
        ClearCollect( Customer, '[SalesLT].[Customer]' ),
        ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' ),
        ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' )
    )
    

    请注意,对第一个按钮添加了相同 ClearCollect 调用,但这一次,它们封装在 Concurrent 函数中,由逗号分隔。

  8. 清除浏览器中的网络监视器。

  9. 如果在此前使用了网络限制,请将其重新打开。

  10. 按住 Alt 键,选择第二个按钮,然后观察网络流量。

    工具会显示同时执行的四个请求,与此示例类似。 再一次,示例中删除了实际时间,因为它们将有很大差异。 图表显示,所有调用在大致相同的时间开始,并不等待上一个调用完成:

    四个网络请求的时间图表,四个请求占用约一半的时间跨度。

    这些图表基于相同的刻度。 通过使用 Concurrent,将完成这些操作所用的时间总量减少了一半。

  11. 保存、关闭并重新打开应用。

争用条件

  1. 向应用添加到 Microsoft Translator 服务的连接。

  2. 添加一个 Text input 控件,然后将其重命名为 TextInput1(如果它具有不同名称)。

  3. 添加 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
        }
    )
    
  4. 添加数据表控件,然后将其 Items 属性设置为 Results

  5. 在右窗格的属性选项卡上,选择编辑字段以打开字段窗格。

  6. 在字段列表中,选中每个字段的复选框,以在数据表中显示它们。

  7. (可选)将 Input 字段拖动到列表顶部,并将 FrenchFaster 字段拖动到列表底部。

    结果集合中字段的列表。

  8. Text input 控件中,键入或粘贴要翻译的短语。

  9. 按住 Alt 键,多次选择按钮以填充该表。

    时间以毫秒为单位显示。

    显示了数据表,其中包含字符串“Hello World”翻译为法语和德语的结果。有时法语翻译比德语快,有时则相反。

    在某些情况下,法语翻译比德语翻译快,有时则相反。 二者同时开始,但由于各种原因(包括网络延迟和服务器端处理),二者相继返回。

    如果应用依赖于一种语言的翻译率先结束,将出现争用条件。 幸运的是,Power Apps 会标志它能检测到的大多数执行时间依赖项。