Microsoft Dynamics 365 Blog

The asyncoperation entity is used in CRM 4.0 to manage various system jobs by the CRM Asynchronous Processing Host (MSCRMAsyncService) windows service. Over time this table accumulates large number of records leading to large databases. This is especially affects organizations that rely on asynchronous plug-ins and workflows. You can use the new Bulk Delete feature ( http://msdn.microsoft.com/en-us/library/cc155955.aspx) to manage the growth of records in the asyncoperation entity table. The bulk delete operation takes as input a QueryExpression and deletes the records returned by the query. There are some things to keep in mind when trying to delete asyncoperation records using bulk delete.



  • You need prvDelete privilege for asyncoperation entity. In a default installation, System Administrator role has this privilege.

  • You need prvBulkDelete privilege to call the BulkDelete API. In a default installation, System Administrator role has this privilege.

  • Only asyncoperation records in Completed state can be deleted.

  • If workflow type asyncoperations are deleted, you will lose history for some records.

In the example below, I have added a condition to select records that are completed for more than one month ago and are not workflow instances.


private static void DeleteCompletedAsyncOperationRecords(CrmService crmService)


{



QueryExpression expression = new QueryExpression(EntityName.asyncoperation.ToString());


expression.ColumnSet = new ColumnSet(new string[] { “asyncoperationid” });


expression.Criteria.AddCondition(“statecode”, ConditionOperator.Equal, (int)AsyncOperationState.Completed);


expression.Criteria.AddCondition(“completedon”, ConditionOperator.OlderThanXMonths, 1);


expression.Criteria.AddCondition(“operationtype”, ConditionOperator.NotEqual, (int)AsyncOperationType.Workflow);


Guid[] emptyRecipients = new Guid[0];


BulkDeleteRequest request = new BulkDeleteRequest();


request.JobName = “Bulk delete completed asyncoperations to free up space”;


request.QuerySet = new QueryBase[] { expression };


request.ToRecipients = emptyRecipients;


request.CCRecipients = emptyRecipients;


request.SendEmailNotification = false;


request.RecurrencePattern = string.Empty;


request.StartDateTime = CrmDateTime.Now;


BulkDeleteResponse response = (BulkDeleteResponse)crmService.Execute(request);


Console.WriteLine(“Bulk delete job id: {0}”, response.JobId);


}


The bulk delete request is processed by MSCRMAsyncService in the background. Depending on the number of records returned by the query, the operation may take from minutes to hours to complete. You can monitor the status of the operation by selecting Settings àData Management à Bulk Record Deletion.


async2


The number of records deleted (and failed to delete) are tracked by the feature and displayed in the grid.


Async


The bulk delete operation can be scheduled as a recurring operation by setting the value of RecurrencePattern. If you plan to do so, I suggest that you run a non-recurring operation and wait for it to run to completion before creating the recurring operation. The AsyncOperationBase table contains thousands of records that would be deleted by the first time by the Bulk Delete operation. It may take several hours to delete the records because each record is deleted using a call to CRM SDK’s Delete method. Once the initial cleanup is done, you can create a recurring operation which should delete only a few records each time it runs. If you are considering adding a recurring system job to do the cleanup, I suggest a weekly frequency and running at off-peak usage times


request.RecurrencePattern = “FREQ=DAILY;INTERVAL=7;”;


request.StartDateTime = CrmTypes.CreateCrmDateTimeFromUser(DateTime.Today.AddDays(1)); // start at midnight tomorrow


You may not see an immediate change in the database size. The records are physically deleted from the AsyncOperationBase table by DeletionService, which runs once a day. After the records are physically deleted by DeletionService, you may need to run “DBCC SHRINKDATABASE” against the organization database to see the actual space usage.


Cheers,


Mahesh Vijayaraghavan

We're always looking for feedback and would like to hear from you. Please head to the Dynamics 365 Community to start a discussion, ask questions, and tell us what you think!