-1

I have a List of objects. I need to make a call to a method of every item in that list. The method is a complex one and it takes time to complete. I am searching a way to call every method in a different thread and then wait for all to finish.

Here is my actual approach (is not working right now):

List<Task> TaskList = new List<Task>();
foreach (ComplexObject co in population)
{
    TaskList.Add(Task.Run(() => co.ComplexTask()));
}
Task.WaitAll(TaskList.ToArray());

Right now I'am getting exceptions in the ComplexTask:

enter image description here

I can execute the ComplexMethod synchronously without errors.

I assume that I'm making mistakes and I need help with the task/await usage.

Thanks.

Edit:

ComplexTask:

    public int ComplexTask()
        {
            int maquinaCubierta = 100;
            int maquinasNoCubierta = -100;

            int empleadoHabitual = 50;
            int empleadoNoHabitual = 25;
            int empleadoAVarios = 15;

            int empleadoCambioTurno = -75;

            int ett = -10;

            fitness = 0;

            bool perfecto = true;

            procesarCalendario();

            for (int dia = 0; dia < 5; dia++)
            {
                for (int turno = 0; turno < 3; turno++)
                {
                    foreach (String key in asignaciones[dia][turno].Keys)
                    {
                        if (asignaciones[dia][turno][key] == null)
                        {
                            if (puestosSemana[dia][turno][0].Contains(key))
                            {
                                fitness += maquinaCubierta + ett;
                            }
                            else
                            {
                                fitness += maquinasNoCubierta;
                                perfecto = false;
                            }
                        }
                        else if (asignaciones[dia][turno][key].kPuesto == key)
                        {
                            fitness += maquinaCubierta;

                            fitness += asignaciones[dia][turno][key].kPuesto == key ? empleadoHabitual : empleadoNoHabitual;

                            if (asignaciones[dia][turno][key].turno != turno + 1)
                            {
                                fitness += empleadoCambioTurno;
                                perfecto = false;
                            }
                        }
                    }

                    fitness += empleadoAVarios * empleadosSinAsignacion[dia][turno].Count;
                }
            }

            if(perfecto)
            {
                fitness = int.MaxValue;
            }

            return fitness;
        }
  • Is the set of tasks running concurrently in your attempt already? Or are they still running in sequence? Are you just asking what a `NullReferenceException` is? It's not clear to me what specific question you're asking. – David Nov 03 '22 at 11:39
  • The task are been created simultaneusly now. But when i do like this the ComplexTask Methods throw a NullReferenceException. If i execute the calls without making tasks then it works perfectly (but very slowly) – Ruben Arranz Nov 03 '22 at 11:41
  • Add a try catch to your loop and look at the `InnerException` property of the exception being thrown. When a Task or Thread has an exception you usually find the actual exception in the `InnerException` property. –  Nov 03 '22 at 11:45
  • 1
    Most likely you have thread-safety issues. Could you edit the question and include the `ComplexTask` method? – Theodor Zoulias Nov 03 '22 at 11:49
  • `await Task.WhenAll(population.Select(co => Task.Run(() => co.ComplexTask())));` However, this probably isn't the answer to your real problem. – Jodrell Nov 03 '22 at 11:52
  • ComplexTask added. But it has calls to another methods and so on... – Ruben Arranz Nov 03 '22 at 11:58
  • What is `fitness`, what does `procesarCalendario();` do? It looks like `fitness` is shared state which will be a problem, you'll need to calculate that in the method and aggregate the combined answer later. – Jodrell Nov 03 '22 at 11:58
  • 2
    The error complains about a SqlConnection. Connections aren't thread-safe and meant to be closed and disposed as soon as possible. Where are you using SqlConnection? If it's shared, don't share it. Create it right before you use it, preferably in a `using` block, to ensure it gets closed even in case of error. ADO.NET's connection pooling ensures there's no extra cost when trying to open a new connection – Panagiotis Kanavos Nov 03 '22 at 12:02
  • Perhaps make fitness a parameter, however, if this is an iterative process it can't be run in parallel/concurrently. – Jodrell Nov 03 '22 at 12:04
  • I'm trying to implement a genetic algorithm. It works fine, but it is very slow. The complexTax is calculating the fitness of every fenotype. I was trying to calculate everyone in a separate thread in order to improve performance. – Ruben Arranz Nov 03 '22 at 12:04
  • 2
    Post the full exception text instead of an image. The full text contains a stack trace with the function calls that resulted in the exception. This will show you which of *your* methods tried to use a SqlConnection – Panagiotis Kanavos Nov 03 '22 at 12:05
  • `I'm trying to implement a genetic algorithm` the error complains about a database connection. Which method is opening a database connection? – Panagiotis Kanavos Nov 03 '22 at 12:06

1 Answers1

1

Perhaps make fitness a parameter, however, if this is an iterative process it can't be run in parallel/concurrently

I was effectively using a shared connection. I'm starting to use unique connections and all seems to work fine now.