2011-09-06 37 views
45

Tôi có ba phương pháp mà tôi gọi là để làm một số crunching số đó như sauCách đơn giản nhất để chạy ba phương pháp song song trong C#

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

Mỗi phòng trong số các chức năng là độc lập với nhau và có thể được tính trong song song không có ổ khóa chết.
Cách dễ nhất để tính toán những điều này song song mà không có phương pháp chứa có kết thúc cho đến khi cả ba được thực hiện?

+0

Bạn chỉ quan tâm đến giải pháp lib tác vụ song song? Điều gì về đơn giản Delegate.BeginInvoke() hoặc thậm chí Thread.Start()? – sll

+0

anh ấy muốn chờ tất cả các kết quả - bạn có thể làm điều này với những gì bạn đề xuất nhưng phải tự đồng bộ hóa - IMHO bạn nên sử dụng Nhiệm vụ vì không có lý do thực sự tốt để làm - điều này thậm chí còn nhiều hơn quan trọng nếu C#/async xuất hiện trực tiếp – Carsten

+0

Tất cả các ví dụ bắt đầu chủ đề tôi đã tìm thấy không đợi cho đến khi nhóm chức năng hoàn thành. – PlTaylor

Trả lời

85

Xem TPL documentation. Họ liệt kê mẫu này:

Parallel.Invoke(() => DoSomeWork(),() => DoSomeOtherWork()); 

Vì vậy, trong trường hợp của bạn này chỉ nên làm việc:

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

EDIT: Các trở về cuộc gọi sau khi tất cả các hành động đã hoàn tất thi công. Invoke() không đảm bảo rằng chúng thực sự sẽ chạy song song, cũng như không bảo đảm thứ tự mà các hành động thực hiện.

+3

Điều này sẽ chờ đợi cho đến khi tất cả các nhiệm vụ song song được hoàn thành? – Jonathan

+1

Đối với tất cả các tìm kiếm tôi đã làm, có vẻ như hầu hết mọi người đã bỏ qua ví dụ đơn giản này. Cảm ơn bạn đã phản hồi nhanh và câu trả lời tuyệt vời. – PlTaylor

+4

@ Jonathan Nó sẽ đợi. Cấu trúc tương tự như bắt đầu một số nhiệm vụ và sau đó gọi 'Task.WaitAll'. – Libor

17

Bạn có thể làm điều này với nhiệm vụ quá (đẹp hơn nếu sau đó bạn cần phải hủy hoặc một cái gì đó giống như kết quả)

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

Có thể không phải là một ý tưởng tốt để sử dụng bắt đầu mới xem: (http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html) – Terry

+2

@dotNETNinja đúng bây giờ - câu trả lời này là khá cũ (như bạn có thể xem) - không có async sau đó - dù sao bạn chỉ có thể chuyển đổi nó bằng ['Task.Run'] (http://msdn.microsoft.com/en-us/library/hh195051 (v = vs.110) .aspx) như được khuyến khích bởi liên kết bạn cung cấp - cho bạn có thể sử dụng .net4.5 (hoặc mới hơn) – Carsten

+0

Tôi có một cái gì đó tương tự ở đây .. http: // stackoverflow.com/questions/30261335/call-methods-parallel-and-kết hợp-kết quả – Ziggler

1

Để chạy các phương thức song song độc lập với nhau ThreadPool.QueueUserWorkItem cũng có thể được sử dụng. Đây là phương pháp luận mẫu

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

Chi tiết về chức năng này có thể được tìm thấy ở đây -
http://newapputil.blogspot.in/2016/03/running-parallel-tasks-using.html

+0

Hoạt động như một sự quyến rũ. Hình như ma thuật mặc dù! –

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

await Task.WhenAll(task1, task2); 

Lợi ích của việc này trong Task.WaitAll là điều này sẽ phát hành các chủ đề và chờ đợi hoàn thành hai nhiệm vụ.

+1

'Parallel' cũng sử dụng luồng hiện tại để thực thi các hành động, vì vậy nó không chặn một luồng đang chờ các hành động được hoàn thành. Nếu bạn có các hoạt động đồng bộ, CPU, bạn cần phải song song, đó là một lựa chọn tốt hơn. –

Các vấn đề liên quan