2011-09-06 35 views
45

我有调用做一些数字运算是如下最简单的方式来运行在并行三种方法在C#

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

的功能中的每是相互独立的,并且可以在计算的三个方法与没有死锁并行。
在完成所有三个任务之前,如果不使用包含方法完成并行计算,最简单的方法是什么?

+0

您只对任务并行lib解决方案感兴趣?直接的Delegate.BeginInvoke()甚至Thread.Start()怎么样? – sll

+0

他想等待所有结果 - 你可以用你的建议做到这一点,但必须自己做同步 - 恕我直言,你应该使用任务,只要没有一些真正的理由不做 - 这将得到更多重要的是如果C#/ async上线 – Carsten

+0

我发现的所有线程启动示例都不等到函数组完成。 – PlTaylor

回答

85

查看TPL documentation。他们列出此示例:

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()不能保证它们确实能够并行运行,也不能保证动作执行的顺序。

+3

这将等待,直到所有并行任务完成? – Jonathan

+1

对于我所做的所有搜索,似乎大多数人都忽略了这个简单的例子。感谢您的快速反应和很好的答案。 – PlTaylor

+4

@Jonathan它会等待。该构造类似于开始几个任务然后调用Task.WaitAll。 – Libor

17

你可以用任务做到这一点太(更好,如果你以后需要取消或类似结果)

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

可能不是一个好主意,使用开始新的看到:(http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html) – Terry

+2

@dotNETNinja现在是真的 - 这个答案是相当古老的(你可以看到) - 没有异步然后 - 无论如何,你可以用['Task.Run'](http://msdn.microsoft.com/en-us/library/hh195051(v = vs.110).aspx )作为您提供的链接建议 - 给你可以使用.net4.5(或更新) – Carsten

+0

我有类似的东西在这里.. http:// stackoverflow。com/questions/30261335/call-methods-parallel-and-combine-results – Ziggler

1

要运行相互独立的并行方法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'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

+0

工程就像一个魅力。看起来像魔术! –

0
var task1 = SomeLongRunningTask(); 
var task2 = SomeOtherLongRunningTask(); 

await Task.WhenAll(task1, task2); 

的这种过度Task.WaitAll的好处是,这将释放线程并等待完成这两项任务。

+1

'Parallel'也使用当前线程执行动作,所以它不会阻塞等待动作完成的线程。如果您需要并行执行同步的CPU限制操作,那么这是一个更好的选择。 –

相关问题