Faster parallel process but duplicate ticket number

1

I have a process that needs to go through a list of 3000 accounts receivable, generate a ticket number, and save. I did a parallel approach that is much faster, but doubles the number of tickets, and a sequential one, which takes 1 minute but does not double.

The code is simplified to not be extensive, but is good near the original.

Approach 1 (This section takes 20 seconds to execute, but doubles the number of tickets)

 Parallel.ForEach(contasReceber, contaReceber =>
 {
     using (var faturaBLO = new Fatura())
     {
         faturaBLO.SalvarContaReceber(contaReceber);
     }
  });

Note: In this approach I need to instantiate an object of Fatura in each iteration because this class has a class variable of type DbContext that is not Thread-Safe. If you instantiate the object faturaBLO outside of ForEach, it gives concurrency error (something like this).

Approach 2 (takes 60 seconds and generates the ticket numbers correctly)

using (var faturaBLO = new Fatura())
{
   foreach (var contaReceber in contasReceber)
   {
      faturaBLO.SalvarContaReceber(contaReceber);
   }
}

Inside the class Fatura is basically this

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 the ticket numbers in the parallel process?

    
asked by anonymous 18.01.2017 / 15:10

0 answers