Faster parallel process but doubles billet number

Asked

Viewed 60 times

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.

  • 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.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.