It is possible that during the 1 hour waiting time, user might reassign again~~again, result of that is multiple same workflow actually is running and waiting at the same time...what we want is just the running the latest workflow instance only.
To solve this problem, create a CRM 4 plugin to query related workflow with specific workflow name, check its status then update it to cancelled.
Register as pre-stage; synchronous, so that it won't cancelled the latest workflow instance .
string error = string.Empty; ColumnSet colsWf = new ColumnSet(new string[] { "name", "statuscode", "asyncoperationid", "regardingobjectid" }); ConditionExpression conditionName = new ConditionExpression("name", ConditionOperator.Equal, workflowName); ConditionExpression conditionRegardingObjectId = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, recordId); FilterExpression filter = new FilterExpression(); filter.FilterOperator = LogicalOperator.And; filter.AddCondition(conditionName); filter.AddCondition(conditionRegardingObjectId); QueryExpression query = new QueryExpression(EntityName.asyncoperation.ToString()); query.Criteria = filter; query.ColumnSet = colsWf; BusinessEntityCollection results = service.RetrieveMultiple(query); if (results.BusinessEntities.Count > 0) { for (int i = 0; i < results.BusinessEntities.Count; i++) { asyncoperation singleWorkflowInstance = (asyncoperation)results.BusinessEntities[i]; if (singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.WaitingForResources || singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.Waiting || singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.InProgress || singleWorkflowInstance.statuscode.Value == AsyncOperationStatus.Pausing) { try { Status statusCanceled = new Status(); statusCanceled.Value = AsyncOperationStatus.Canceled; AsyncOperationStateInfo state = new AsyncOperationStateInfo(); state.Value = AsyncOperationState.Completed; SetStateWorkflowRequest request = new SetStateWorkflowRequest(); singleWorkflowInstance.statuscode = statusCanceled; singleWorkflowInstance.statecode = state; TargetUpdateAsyncOperation operation = new TargetUpdateAsyncOperation(); operation.AsyncOperation = singleWorkflowInstance; UpdateRequest update = new UpdateRequest(); update.Target = operation; UpdateResponse updated = (UpdateResponse)service.Execute(update); } catch (System.Web.Services.Protocols.SoapException ex) { error = "KillWorkflow Error " + ex.Message + "" + ex.StackTrace; } catch (Exception ex) { error = "KillWorkflow Error " + ex.Message + "" + ex.StackTrace; } } } if (!string.IsNullOrEmpty(error)) { throw new Exception(error); } }
superb customization!
ReplyDelete