Hello,
I am creating a service that calls a number of actions. It passes to the methods the required parameters and a userConnection. I pass the UserConnection to the service class using dependency injection:
public class MonitoringService : IMonitoringService { private UserConnection _userConnection; public MonitoringService(UserConnection userConnection) { _userConnection = userConnection; } // the rest of the code here }
this service is run in the background declaring an implementation of creatio's IBackgroundTask and IUserConnectionRequired interfaces.
The actions are executed in parallel, as shown in the code below:
public void ExecuteStepsAsync( Dictionary<Guid, BlockStepExecution> allSteps, BlockExecution blockExecution, Guid applicationId, Guid appFormId, IAppProduct product = null, DateTime? requestStartTime = null) { var processors = Environment.ProcessorCount; var steps = blockExecution.Steps; var workQueue = new Queue<BlockStepExecution>( steps.Values.Where(step => step.IsReady(allSteps)).ToList() ); while (workQueue.Count > 0) { var currentBatch = DequeueBatch(workQueue); var newSteps = new ConcurrentQueue<BlockStepExecution>(); Parallel.ForEach(currentBatch, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, step => { StartStepExecution(step, requestStartTime); try { Execute(step, applicationId, appFormId, product); step.Complete(); } catch (Exception ex) { step.Fail($"FAILED: {ex.Message}"); } StepExecutionFinished(step); var followUp = step.GetConditionalFollowUp(steps.Values); if (followUp != null) newSteps.Enqueue(followUp); }); foreach (var next in steps.Values.Where(s => s.IsReady(allSteps))) workQueue.Enqueue(next); while (newSteps.TryDequeue(out var child)) workQueue.Enqueue(child); //if (!workQueue.Contains(child)) } }
and the method for action execution:
public void Execute(BlockStepExecution step, Guid applicationId, Guid appFormId, IAppProduct product) { if (step.ShouldSkipStep()) { Logger.Info($"Step '{step.FZName}' skipped (ends with '-001')."); return; } var action = _methodRegistry.GetAction(step.FZName); if (action == null) throw new NotImplementedException($"Step not implemented: {step.FZName}"); action(applicationId, appFormId, product, _userConnection); }
Some of the actions that are executed in parallel, call business processes.
In some executions of the business processes I have encountered 2 errors:
and
I think the problem is related to a connection that should be closed but is not and is reused in the next processes.
What could be the cause for these errors and how can I fix this issue?
Thank you in advance!
Like