2013-02-10 35 views
6

Tôi có một vòng lặp tạo nhiều tác vụ như được hiển thị bên dưới. Làm cách nào để cập nhật màn hình (thêm dòng mới vào hộp văn bản với một số dữ liệu) khi mỗi tác vụ hoàn tất?hoàn thành nhiệm vụ

Làm cách nào để phát hiện khi tất cả công việc đã hoàn tất?

C# Mã

for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++) 
{ 
     int x = i; 
     // Create a task and supply a user delegate by using a lambda expression. 
     var taskA = new Task(() => TaskRequest(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxFloodDelay.Text), x)); 
     // Start the task. 
     taskA.Start(); 
} 


private void TaskRequest(int number1, int number2, int delay, int count) 
{ 
     // Some long running method 
} 
+1

bạn muốn kích hoạt khi tất cả công việc của bạn được thực hiện? – bas

+0

có, và khi mỗi nhiệm vụ hoàn thành cũng – user1438082

+1

Parallel.For hoặc Parallel.ForEach có phải là giải pháp cho bạn không? Khó thực sự hiểu những gì bạn đang tìm kiếm. – bas

Trả lời

13

Bạn có thể sử dụng ContinueWith():

"Tạo sự tiếp nối mà thực hiện không đồng bộ khi mục tiêu nhiệm vụ hoàn thành." - MSDN

Task t = new Task(() => Console.WriteLine("")).ContinueWith(task => Console.Writeline("Continue With"), 
                  TaskScheduler.FromCurrentSynchronizationContext()); 
+4

Bạn cần thêm paramater TaskScheduler.FromCurrentSynchronizationContext nếu bạn định cập nhật giao diện người dùng, bạn có thể đang ở một chủ đề khác. – Jesse

+0

làm cách nào để đặt mã này vào mã của tôi? – user1438082

+0

Trước khi khung cuối cùng thêm ", TaskScheduler.FromCurrentSynchronizationContext" – Jesse

1

tôi khuyên bạn nên sử dụng một sự kết hợp của 3 cấu trúc đơn giản:

  • một đơn giản int numActiveTasks, đó là tăng lên với InterlockedIncrement(ref numActiveTasks) trên tạo ra nhiệm vụ, tức là ngay trước taskA.Start() và giảm ở InterlockedDecrement(ref numActiveTasks) ở cuối nhiệm vụ, nghĩa là ở cuối chức năng TaskRequest(...)
  • một ManualResetEvent, được đặt lại trước khi bắt đầu nhiệm vụ và hiệu kết thúc nhiệm vụ sau quầy giảm giá trị
  • a thread, mà WaitOne() s trên ManualResetEvent, sau đó đọc numActiveTasks

này mang đến cho bạn

  • notfication của nhiệm vụ duy nhất thực hiện
  • thông báo về tất cả các công việc đã thực hiện (numActiveTasks < = 0)

Ưu điểm chính của việc này là, bạn có chủ quyền về việc chuỗi thông báo nào xuất hiện.

+0

xin chào, bạn có thể vui lòng cung cấp một số mã cho điều này để minh họa cách thực hiện điều này không? – user1438082

1

Bạn đang tìm kiếm Parallel.ForEach()?

[Test] 
    public void ParallelTasks() 
    { 
     var strings = new List<string> {"task1", "task2", "task3"}; 

     Parallel.ForEach(strings, str => Console.WriteLine(str + "is done")); 

     // All your parallel tasks are executed now 
    } 
1

Mở rộng câu trả lời của người dùng 12345678, bạn có thể làm như sau.

private void RunTasks() 
    { 
     Dictionary<string, string> dict = new Dictionary<string, string>(); 

     List<Task> tasks = new List<Task>(); 
     foreach (KeyValuePair<string,string> kvp in dict) 
     { 
      Console.WriteLine("Executing task " + kvp.Key + " ..."); 
      Task t = new Task(() => MyMethod(kvp.Key, kvp.Value)); 
      tasks.Add(t); 
      t.Start(); 
      t.ContinueWith(task => Console.WriteLine(kvp.Key + " completed")); 

     } 

     Console.WriteLine("Waiting tasks to complete..."); 
     Task.WaitAll(tasks.ToArray()); 
     Console.WriteLine("All tasks completed..."); 
    } 

    private void MyMethod(string arg1, string arg2) 
    { 

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