2010-10-13 11 views
7

Chúng tôi đang chuyển ứng dụng mô hình hóa, sử dụng các kịch bản IronPython cho các hành động tùy chỉnh trong quá trình tạo mô hình. Ứng dụng hiện có thực hiện từng kịch bản lệnh Python trong chuỗi riêng biệt và sử dụng mô hình hợp tác cho việc này. Bây giờ chúng tôi muốn chuyển nó sang TPL, nhưng trước tiên chúng tôi muốn đo chuyển đổi ngữ cảnh . Về cơ bản, những gì chúng tôi có ngay bây giờ:Hợp tác đa tác vụ bằng cách sử dụng TPL

  1. Task s đợi
  2. mỗi Task từ hàng đợi này thực hiện một IronPython kịch bản
  3. Bên IronPython kịch bản mà chúng ta gọi cho C# lớp phương pháp, đó là điểm đồng bộ hóa và nên chuyển Task (IronPython thực hiện) để chờ đợi nhà nước

gì chúng tôi muốn làm:

  1. Chúng tôi muốn thực hiện vòng lặp vô hạn, mà sẽ lặp qua Task s đợi
  2. khi chúng ta có được một Task chúng tôi cố gắng thực hiện nó
  3. Trong PythonScript chúng tôi muốn gọi C phương pháp # và chuyển kịch bản này để chờ đợi nhà nước. nhưng không xóa nó khỏi hàng đợi.
  4. Khi lặp lại lần tiếp theo khi chúng tôi nhận được Task khác, chúng tôi kiểm tra xem có đang ở trạng thái đợi không. nếu chúng ta đánh thức nó và cố gắng thi hành.
  5. Trong mỗi khoảnh khắc chúng ta nên chỉ có một hoạt động Task
  6. Và cuối cùng chúng tôi muốn để đo lường bao nhiêu Task chúng ta có thể thực hiện trong một giây

Tôi thật sự không biết là nó điều gì đó về đa nhiệm hợp tác xã? Chúng tôi đang suy nghĩ về tùy chỉnh TaskScheduler, là phương pháp tiếp cận tốt? Hay ai đó biết giải pháp tốt hơn?

Cảm ơn.

Cập nhật:

Ok, ví dụ như vậy, tôi có mã như:

public class CooperativeScheduler : TaskScheduler, IDisposable 
    { 
     private BlockingCollection<Task> _tasks; 

     private Thread _thread; 

     private Task _currentTask; 

     public CooperativeScheduler() 
     { 
      this._tasks = new BlockingCollection<Task>(); 
      this._thread = new Thread(() => 
       { 
        foreach (Task task in this._tasks.GetConsumingEnumerable()) 
        { 
         this._currentTask = task; 

         TryExecuteTask(this._currentTask); 
        } 
       } 
      ); 

      this._thread.Name = "Cooperative scheduler thread"; 

      this._thread.Start(); 
     } 

     public void SleepCurrentTask() 
     { 
      if (this._currentTask != null) 
      { 
       // what to do here? 
      } 
     } 

     protected override IEnumerable<Task> GetScheduledTasks() 
     { 
      return this._tasks.ToArray<Task>(); 
     } 

     protected override void QueueTask(Task task) 
     { 
      // No long task 
      this._tasks.Add(task); 
     } 

     protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) 
     { 
      throw new NotImplementedException(); 
     } 

     public void Dispose() 
     { 
      this._tasks.CompleteAdding(); 
      this._thread.Join(); 
     } 
    } 

Tuỳ chỉnh Task Scheduler, nó đã một _thread cho công tác thi công và _currentTask lĩnh vực để chạy nhiệm vụ, cũng có thể nó có SleepCurrentTask trong phương thức này, tôi muốn tạm ngừng thực hiện Task hiện tại, nhưng tôi không biết làm thế nào.

Khách hàng mã rất đơn giản:

CancellationTokenSource tokenSource = new CancellationTokenSource(); 
    Application app = Application.Create(); 


    Task task = Task.Factory.StartNew(() => 
    { 
     app.Scheduler.SleepCurrentTask(); 
    }, 
    tokenSource.Token, TaskCreationOptions.None, app.Scheduler); 
} 

Có lẽ ai đó có ý tưởng tốt hơn?

Trả lời

1

Có vẻ như bạn sẽ được phục vụ tốt để sử dụng mẫu nhà sản xuất/người tiêu dùng .NET 4 đã được tích hợp vào một vài bộ sưu tập.

Kiểm tra trang 55 trong tệp PDF miễn phí này từ Microsoft, Patterns of Parallel Programming