es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Parallel.ForEach con una lista devuelve datos repetidos o vacíos.

El código debe ejecutar un método POST en el servidor y, en función de la información recibida, llenar una lista de elementos. El código es algo como esto:

var parallelResult= Parallel.ForEach(myList,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling(
            (Environment.ProcessorCount * 0.75) * 3.0))
    },
    item => {
        msg = string.Empty;
        msg = item.fullName;
        var balance = users.balance(item.id);
        if (balance.amount > 0 && balance.isReady)
        {
            var sendResponse = users.send(item.id, balance.amount);
            tbeResponse data;
            data = JsonConvert.DeserializeObject<tberesponse>(sendResponse);

            if (data.success)
            {
                _context.users.Add(item);
                msg += " añadido: " + sendResponse;
                q++;
            }
            else
            {
                msg += " no pudo ser añadido: " + sendResponse;
            }
        }
        else
        {
            msg += " balance=0";
        }
    });

if(parallelResult.IsCompleted)
    _context.SaveChanges();
response.Add($"{q} fueron añadidos a la base de datos. Y se necesitan firmar");
return Ok(response);

El problema está en el objeto de respuesta. Puede contener elementos repetidos, fragmentos repetidos, mensajes inconsistentes o elementos faltantes como:

none
Diego Maradona
Diego Maradona
Diego Maradona no pudo ser añadido:
Diego Maradona añadido: {json response}
Ariel Ortega balance 0
Lio Messi balance=0 balance=0 balance=0
10 fueron añadidos a la base de datos. Y se necesitan firmar

Debería haber un problema con la pieza de código msg+, pero no encuentro una manera de solucionarlo. El elemento int q++ funciona bien. El problema está con la cadena y cuando se agrega información a la variable en msg += "algún texto". ¿Alguna idea?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución para solucionar este problema con el código msg+ podría ser usar un StringBuilder en lugar de concatenar cadenas con +=. Esto mejoraría el rendimiento y reduciría la posibilidad de mensajes inconsistentes.

    El código actualizado podría verse así:

    var responseBuilder = new StringBuilder();
    var q = 0;
    
    Parallel.ForEach(myList, new ParallelOptions
    {
        MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 3.0))
    }, item =>
    {
        var messageBuilder = new StringBuilder();
        messageBuilder.Append(item.fullName);
    
        var balance = users.balance(item.id);
        if (balance.amount > 0 && balance.isReady)
        {
            var sendResponse = users.send(item.id, balance.amount);
            var data = JsonConvert.DeserializeObject<tberesponse>(sendResponse);
    
            if (data.success)
            {
                _context.users.Add(item);
                messageBuilder.Append(" agregado: ").Append(sendResponse);
                Interlocked.Increment(ref q);
            }
            else
            {
                 messageBuilder.Append(" no se pudo agregar: ").Append(sendResponse);
            }
        }
        else
        {
            messageBuilder.Append(" balance=0");
        }
    
        lock (responseBuilder)
        {
            responseBuilder.AppendLine(messageBuilder.ToString());
        }
    });
    
    _context.SaveChanges();
    responseBuilder.AppendLine($"{q} fueron agregados a la base de datos. Y deben ser firmados");
    return Ok(responseBuilder.ToString());
    

    Algunos cambios en el código incluyen:
    – Usar un StringBuilder para construir el mensaje para cada elemento procesado en el bucle.
    – Usar Interlocked.Increment para incrementar q de manera segura en los hilos.
    – Usar lock para agregar mensajes al StringBuilder de respuesta.
    – Eliminar la comprobación if (parallelResult.IsCompleted), ya que no es necesario ya que el método SaveChanges se llama después de que finaliza el bucle.

    ¡Espero que esto ayude!

Comments are closed.