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!