Collaborative multitasking using TPL

We are porting a simulation application that uses IronPython scripts for custom actions in the simulation process. An existing application runs each Python script in a separate thread and uses a collaborative model for this. Now we want to transfer it to TPL, but first we want to measure context switching, Basically, what we have right now:

  • Task queues
  • each Task from this queue executes one IronPython script
  • Inside the IronPython script, we call the C # class method, which is the synchronization point and should put the Task (IronPython execution) in the idle state

What we want to do:

  • We want to create an infinite loop that will go through the Task queue
  • when we get one Task , we try to execute it
  • In PythonScript, we want to call the C # method and pass this state of the script to the wait state. but do not remove it from the queue.
  • At the next iteration, when we get another Task , we check this in the idle state. if so, we wake him up and try to execute.
  • At each moment in time we should have only one active Task
  • And finally, we want to measure how much Task we could complete per second

I really don't know, is this something like collaborative multitasking? We are thinking of custom TaskScheduler , is this a good approach? Or does someone know a better solution?

Thanks.

Updated:

Well, for example, I have this code:

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

A user task scheduler, it has one _thread for executing the task and _currentTask for starting the task, it also has SleepCurrentTask in this method. I want to pause the current task, but I do not know how to do it.

Client code is simple:

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

Maybe someone has better ideas?

+7
python multithreading c # scheduled-tasks task
source share
1 answer

It looks like the .NET 4 producer / consumer pattern, which is built into several collections, will serve you well.

Browse page 55 in this free PDF from Microsoft, Parallel Programming Templates

+1
source share

All Articles