Простейший способ одновременного запуска трех методов в С#
У меня есть три метода, которые я вызываю для выполнения некоторого числа хруста, следующие
results.LeftFront.CalcAi();
results.RightFront.CalcAi();
results.RearSuspension.CalcAi(geom, vehDef.Geometry.LTa.TaStiffness, vehDef.Geometry.RTa.TaStiffness);
Каждая из функций независима друг от друга и может быть вычислена параллельно без мертвых замков.
Каков самый простой способ вычислить их параллельно без завершения метода до тех пор, пока все три не будут выполнены?
Ответы
Ответ 1
См. документацию TPL. Они перечисляют этот пример:
Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());
Итак, в вашем случае это должно сработать:
Parallel.Invoke(
() => results.LeftFront.CalcAi(),
() => results.RightFront.CalcAi(),
() => results.RearSuspension.CalcAi(geom,
vehDef.Geometry.LTa.TaStiffness,
vehDef.Geometry.RTa.TaStiffness));
EDIT:. Вызов возвращается после завершения всех действий. Invoke()
не гарантирует, что они действительно будут работать параллельно, а также не гарантирует порядок выполнения действий.
Ответ 2
Вы можете сделать это тоже с задачами (лучше, если вам понадобится аннулирование или что-то вроде результатов)
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);
Ответ 3
В .NET 4 Microsoft представила параллельную библиотеку задач, которая была разработана для решения этой проблемы, см. Параллельное программирование в .NET Framework.
Ответ 4
Для запуска параллельных методов, которые не зависят друг от друга ThreadPool.QueueUserWorkItem также можно использовать. Вот пример метода -
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 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);
}
Подробнее об этой функции можно найти здесь -
http://newapputil.blogspot.in/2016/03/running-parallel-tasks-using.html
Ответ 5
var task1 = SomeLongRunningTask();
var task2 = SomeOtherLongRunningTask();
await Task.WhenAll(task1, task2);
Преимущество этого над Task.WaitAll заключается в том, что это освободит поток и ждет завершения двух задач.