1
I have a process that needs to go through a list of 3000 accounts receivable, generate a billet number and save. I made an approach in parallel that is much faster, but doubles the number of billets, and a sequential, which takes 1 minute but does not duplicate.
The code is simplified to not be extended, but is good next to the original.
Approach 1 (This section takes 20 seconds to execute, but doubles the number of billets)
 Parallel.ForEach(contasReceber, contaReceber =>
 {
     using (var faturaBLO = new Fatura())
     {
         faturaBLO.SalvarContaReceber(contaReceber);
     }
  });
Note: In this approach we need to instantiate an object of Fatura in each iteration as this class has a class variable of the type DbContext which is not Thread-Safe. Instantiating the object faturaBLO out of Foreach, gives error of competition(something like).
Approach 2 (takes 60 seconds and generates billet numbers correctly)
using (var faturaBLO = new Fatura())
{
   foreach (var contaReceber in contasReceber)
   {
      faturaBLO.SalvarContaReceber(contaReceber);
   }
}
Within the class Fatura that’s basically it
public string ProximoNossoNumero(long codigoConta)
{
            int nossoNumero = 0;
            string stringNossoNumero = ctx.tbConta.Where( c=>c.codigoConta== codigoConta)
                                                  .Select(c => c.ultimoNossoNumero)
                                                  .FirstOrDefault();
            if (!string.IsNullOrWhiteSpace(stringNossoNumero))
            {
                int.TryParse(stringNossoNumero, out nossoNumero);
            }
            return (nossoNumero + 1).ToString("D8");
 }
 public void AtualizarNossoNumero(long codigoConta, string nossoNumero)
    {
        tbConta conta = ctx.tbConta.FirstOrDefault(c => c.codigoConta== codigoConta);
        if (conta != null)
        {
            conta.ultimoNossoNumero= nossoNumero;
            ctx.Entry(conta).State = EntityState.Modified;
            ctx.SaveChanges();
        }
    }
   public void SalvarContaReceber(tbContaReceber contaReceber)
   {
      contaReceber.nossoNumero = ProximoNossoNumero(contaReceber.codigoContaBoleto);
      ctx.tbContaReceber.Add(contaReceber);
      ctxt.SaveChanges();
      AtualizarNossoNumero(contaReceber.codigoContaBoleto, contaReceber.nossoNumero);
   }
Any alternative to eliminate this duplication in billet numbers in the parallel process?
Read this: http://answall.com/q/1946/101. I’m not saying I can’t do anything to improve, because I haven’t analyzed the details (nor have all of them), but it seems that this case done the right way will not bring significant advantage in parallelizing.
– Maniero
True. In this case I don’t think it will. The generation of numbers has to be sequential anyway. I’ll leave the parallelism for the generate PDF files section of the boleto.
– user26552