Простейший способ одновременного запуска трех методов в С#

У меня есть три метода, которые я вызываю для выполнения некоторого числа хруста, следующие

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

Ответ 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 заключается в том, что это освободит поток и ждет завершения двух задач.