Search code examples
dynamics-crmmicrosoft-dynamicsdynamics-crm-2015

Get systemjob id of current running system job (AsyncOperation Entity)


I'm writing a Dynamics CRM 2015 plugin, that is triggered by the sdk message step "assign of Task" and runs asynchronously.

In Execute(IServiceProvider serviceProvider) method, I want to search for other currently running system jobs, using a QueryExpression:

QueryExpression systemjobq = new QueryExpression
{
    EntityName = "asyncoperation",
    ColumnSet = new ColumnSet("name", "createdon", "completedon", "regardingobjectid", "asyncoperationid", "startedon", "messagename", "statuscode"),
    Criteria = new FilterExpression
    {
        Conditions = {
                        new ConditionExpression 
                        {
                            AttributeName = "name",
                            Operator = ConditionOperator.Equal,
                            Values = { "My system jobs name" }
                        }
                     }
    }
};

Because I don't want to find "myself" - the currently running system job - I need to find out the asyncoperationid of the currently running system job that executes my plugin, so I can include it in my search query expression.

How can I find out the asyncoperationid of the currently running system job?


Solution

  • If I understand correctly, you would like to find the record of the async job in which your async plugin is currently executing. Try the following extension method:

       public static EntityCollection GetCurrentAsyncJob(this IOrganizationService service, ColumnSet cols, Guid EntityId, Guid OwnerId) {
    
                QueryExpression systemjobq = new QueryExpression
                {
                    EntityName = "asyncoperation",
                    ColumnSet = cols,//new ColumnSet("name", "createdon", "completedon", "regardingobjectid", "asyncoperationid", "startedon", "messagename", "statuscode"),
                    Criteria = new FilterExpression
                    {
                        Conditions = 
                        {
                            new ConditionExpression 
                            {
                                AttributeName = "regardingobjectid",
                                Operator = ConditionOperator.Equal,
                                Values = {EntityId}
                            },
                            new ConditionExpression {
                            AttributeName = "statuscode",
                            Operator = ConditionOperator.In,
                            Values = {20}
                            },
                            new ConditionExpression 
                            {
                                AttributeName = "ownerid",
                                Operator = ConditionOperator.Equal,
                                Values = {OwnerId}
                            }
                        }
                    }
                };
                systemjobq.Orders.Add(new OrderExpression { AttributeName = "createdon", OrderType = OrderType.Descending });
                return service.RetrieveMultiple(systemjobq);
            }
    

    You can check if you are getting an Id of the Async job as follows, where service is your IOrganization service in the plugin and taskId is the id of your task, against which the plugin is currently running, and the OwnerId is the current initiating owner of the plugin:

         EntityCollection ents = service.GetCurrentAsyncJob(new ColumnSet(new []{"name", "createdon", "completedon", "regardingobjectid", "asyncoperationid", "startedon", "messagename", "statuscode"}), TaskId, OwnerId);
                if (ents.Entities.Count > 0)
                    throw new InvalidPluginExecutionException(ents.Entities.FirstOrDefault().Id.ToString());
                else throw new InvalidPluginExecutionException("M? Really, No?");
    

    This is how you get the current user in the plugin, from your plugin context:

    Guid userId = context.InitiatingUserId;
    

    The method is not perfect, as it will return multiple jobs if they exist related to this entity, and the assign is fired for the same task concurrently. I am not sure and have not tested this, though I think it will only be a problem if your plugin is selected to run under the same user.

    Note that the extension method must be placed in a static class.

    Note2: Status equal to 20 means the async job is still running and InProgress.

    Please try and see if it works out for you.