这是我的第505篇原创文章,写于2023年11月25日。

项目中可能会碰到Flow (Power Automate) 看起来没有被触发,但是偶尔又能触发的样子。这时候请检查下系统作业表(asyncoperation)是否记录太多。

至于查看这个实体的元数据信息可以通过类似 https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/EntityDefinitions(LogicalName='asyncoperation')   的URL来查看,因为这个表在默认解决方案中也看不到。如果要看所有列的信息可以通过 https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/EntityDefinitions(LogicalName='asyncoperation')/Attributes  的URL来查看。如果要看某个具体列的信息则可以通过 https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/EntityDefinitions(LogicalName='asyncoperation')/Attributes(LogicalName='statecode') 的URL来查看。

重要的列就是statecode和statuscode,但是通过 

https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/EntityDefinitions(LogicalName='asyncoperation')/Attributes(LogicalName='statuscode')/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options),GlobalOptionSet($select=Options)

这样的URL查不到值列表。却可以通过类似

https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/stringmaps?$select=attributevalue,value,langid&$filter=objecttypecode eq 'asyncoperation' and attributename eq 'statuscode' and langid eq 2052

这样的URL看到。

我这里讲值列出来如下:

表名

字段名

存储值

显示值

asyncoperation

statecode

0

准备就绪

asyncoperation

statecode

1

暂停

asyncoperation

statecode

2

已锁定

asyncoperation

statecode

3

已完成

asyncoperation

statuscode

0

正在等待资源

asyncoperation

statuscode

10

等待中

asyncoperation

statuscode

20

正在进行

asyncoperation

statuscode

21

正在暂停

asyncoperation

statuscode

22

正在取消

asyncoperation

statuscode

30

成功

asyncoperation

statuscode

31

失败

asyncoperation

statuscode

32

已取消


如果要看这个表有多少条记录呢?根据 Query data using the Web API 的说法,如果表中的记录不超过5万行的话,可以用类似

https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/asyncoperations?$apply=aggregate($count as count)

这样的语句查看。如果要看不同状态statuscode下记录数的汇总的话可以通过类似

https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/asyncoperations?$apply=groupby((statuscode),aggregate($count as count))

这样的语句查看。

如果超过5万行报错的话,还可以通过 RetrieveTotalRecordCount Function 来看,但是这个不是很准,是过去24小时的快照,示例如下:

https://luoyongdemo.crm.dynamics.cn/api/data/v9.2/RetrieveTotalRecordCount(EntityNames=['asyncoperation'])


如果statuscode < 30的记录太多,那就可能是异步服务队列积压了,这时候怎么办?清理呗。有些系统作业或许可以取消,比如说程序bug导致了大量误触发,或者某些系统标准的异步插件(见下图是一个典型的与linkin相关的但是我们中国大陆版本不需要的功能)被触发了很多次等,这时候可以考虑取消还没有运行的但是没有用的系统作业。

碰到Flow没有运行但是很多系统作业等待情况的处理方法_Power Platform


最好是找准取消哪些系统作业,可以找一些出来看看,比如我看到某个很多系统作业等待运行的很多就取消这个,我一般通过XrmToolBox 中的 SQL 4 CDS 工具来进行处理,类似SQL如下:

这里有个技巧就是要先处理最近产生的记录,也就是createdon字段比较大的。不然的话执行可能会报错,一次处理不了多少。当然可以不断的处理,一次处理的记录不要超过10万条。

update asyncoperation set statecode=3,statuscode=32 
where owningextensionid='045e1e42-bdd1-4b4f-b3c5-7bbc0f724ee7' and statecode in (0,1,2) 
and createdon> '2023-11-16 07:00:00.000' and createdon<'2023-11-16 08:30:00.000'


用SQL处理起来快,但是如果要用代码呢,可以使用类似如下的FetchXml执行分页查询,

<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
  <entity name='asyncoperation'>
    <attribute name='asyncoperationid' />
    <attribute name='name' />
    <attribute name='statuscode' />
    <attribute name='statecode' />
    <order attribute='startedon' descending='true' />
    <filter type='and'>
      <condition attribute='name' operator='eq' value='{作业名称}' />
      <condition attribute='statecode' operator='in'>
        <value>0</value>
        <value>1</value>
        <value>2</value>
      </condition>
    </filter>
  </entity>
</fetch>


然后将查找出来的系统作业取消,类似下面的代码:

using Microsoft.Xrm.Sdk;
using System;
foreach (var entity in lstEntity)
{
    Entity systemJob = new Entity("asyncoperation", entity.Id);
    systemJob["statuscode"] = new OptionSetValue(32);
    systemJob["statecode"] = new OptionSetValue(3);
    try
    {
        orgService.Update(systemJob);

    }
    catch (Exception ex)
    {
        Console.WriteLine(string.Format("取消作业 {0} 失败! {ex.message}", entity.Attributes.FirstOrDefault(attr => attr.Key == "name").Value));
    }
}


当然逐条处理太慢,可以批量处理,请参考我的文章:Dynamics 365使用Execute Multiple Request删除系统作业实体记录

如果不是要取消指定的系统作业而是全部取消,还有别的办法,就是将进入Power Platform Admin Center将这个环境(environment)的Aministrator mode打开,Background operations保持为Disabled状态。过一阵子所有的异步系统作业就会被取消了,取消完成了再恢复成正常模式就可以了。

碰到Flow没有运行但是很多系统作业等待情况的处理方法_Power Apps_02

我还有些其他文章可以参考用于解决排查类似问题如下: