web-dev-qa-db-fra.com

Le moyen le plus simple d'exécuter trois méthodes en parallèle en C #

J'ai trois méthodes que j'appelle pour faire des calculs qui sont comme suit

results.LeftFront.CalcAi();  
results.RightFront.CalcAi();  
results.RearSuspension.CalcAi(geom, vehDef.Geometry.LTa.TaStiffness, vehDef.Geometry.RTa.TaStiffness);

Chacune des fonctions est indépendante l’une de l’autre et peut être calculée en parallèle sans blocage.
Quel est le moyen le plus simple de les calculer en parallèle sans que la méthode contenant ne se termine avant que les trois ne soient terminées?

54
PlTaylor

Voir la Documentation TPL . Ils listent cet exemple:

Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());

Donc, dans votre cas, cela devrait fonctionner:

Parallel.Invoke(
    () => results.LeftFront.CalcAi(),
    () => results.RightFront.CalcAi(),
    () => results.RearSuspension.CalcAi(geom, 
                                        vehDef.Geometry.LTa.TaStiffness, 
                                        vehDef.Geometry.RTa.TaStiffness));

EDIT: L'appel revient une fois que toutes les actions ont été exécutées. Invoke() is ne garantit pas qu’elles seront exécutées en parallèle, ni l’ordre dans lequel les actions sont exécutées.

102
Sander Rijken

Vous pouvez également le faire avec des tâches (plus pratique si vous avez besoin ultérieurement d'une annulation ou de résultats similaires).

var task1 = Task.Factory.StartNew(() => results.LeftFront.CalcAi());
var task2 = Task.Factory.StartNew(() => results.RightFront.CalcAi());
var task3 = Task.Factory.StartNew(() =>results.RearSuspension.CalcAi(geom, 
                              vehDef.Geometry.LTa.TaStiffness, 
                              vehDef.Geometry.RTa.TaStiffness));

Task.WaitAll(task1, task2, task3);
17
Carsten

Dans .NET 4, Microsoft a introduit la bibliothèque de tâches parallèle, conçue pour traiter ce type de problème. Voir Programmation parallèle dans le .NET Framework .

2
Shiraz Bhaiji

Pour exécuter des méthodes parallèles indépendantes les unes des autres, vous pouvez également utiliser ThreadPool.QueueUserWorkItem. Voici l'exemple de méthode 

public static void ExecuteParallel(params Action[] tasks)
{
    // Initialize the reset events to keep track of completed threads
    ManualResetEvent[] resetEvents = new ManualResetEvent[tasks.Length];

    // Launch each method in it's own thread
    for (int i = 0; i < tasks.Length; i++)
    {
        resetEvents[i] = new ManualResetEvent(false);
        ThreadPool.QueueUserWorkItem(new WaitCallback((object index) =>
            {
                int taskIndex = (int)index;

                // Execute the method
                tasks[taskIndex]();

                // Tell the calling thread that we're done
                resetEvents[taskIndex].Set();
            }), i);
    }

    // Wait for all threads to execute
    WaitHandle.WaitAll(resetEvents);
}

Plus de détails sur cette fonction peuvent être trouvés ici:
http://newapputil.blogspot.in/2016/03/running-parallel-tasks-using.html

1
nvivekgoyal
var task1 = SomeLongRunningTask();
var task2 = SomeOtherLongRunningTask();

await Task.WhenAll(task1, task2);

L'avantage de cela par rapport à Task.WaitAll est que cela va libérer le thread et attendre la fin des deux tâches.

0
Brett Mealor