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?
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.
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);
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 .
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
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.