Самый простой способ запустить три метода параллельно в C # - PullRequest
59 голосов
/ 06 сентября 2011

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

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

Каждая из функций не зависит друг от друга и может быть вычислена параллельно без мертвых блокировок.
Какой самый простой способ вычислить их параллельно, не завершив содержащий метод, пока все три не будут выполнены?

Ответы [ 5 ]

109 голосов
/ 06 сентября 2011

См. Документацию 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));

РЕДАКТИРОВАТЬ: Вызов возвращается после завершения всех действий. Invoke() is не гарантирует, что они действительно будут работать параллельно, и не гарантирует порядок, в котором выполняются действия.

18 голосов
/ 06 сентября 2011

Вы можете сделать это и с задачами (лучше, если вам позже понадобится отмена или что-то вроде результатов)

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 голосов
/ 10 марта 2016

Для запуска параллельных методов, которые не зависят друг от друга Вот пример метода -

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

Подробнее об этой функции можно узнать здесь:
http://newapputil.blogspot.in/2016/03/running-parallel-tasks-using.html

2 голосов
/ 06 сентября 2011

В .NET 4 Microsoft представила параллельную библиотеку задач, которая была разработана для решения подобных проблем, см. Параллельное программирование в .NET Framework .

0 голосов
/ 11 июля 2016
var task1 = SomeLongRunningTask();
var task2 = SomeOtherLongRunningTask();

await Task.WhenAll(task1, task2);

Преимущество этого перед Task.WaitAll заключается в том, что это освободит поток и будет ждать завершения двух задач.

...