We are porting modeling application, which uses IronPython scripts for custom actions in modeling process. The existing application executes each Python script in separate thread and uses cooperative model for this. Now we want to port it to TPL, but first we want to measure context switching . Basically, what we have right now:
Task
s queueTask
from this queue executes one IronPython scriptTask
(IronPython execution) to waiting stateWhat we want to do:
Task
s queueTask
we try to execute itTask
we check is it in the waiting state. if so we wake it up and try to execute.Task
Task
we could execute per secondI don't really know is it something about cooperative multitasking?
We are thinking about custom TaskScheduler
, is it good approach? Or does someone know better solution?
Thanks.
Updated:
Ok ,so for example, I have such 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();
}
}
Custom Task Scheduler, it has one _thread
for Task execution and _currentTask
field for running task, also it has SleepCurrentTask
in this method I want to suspend current Task execution, but I don't know how.
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?
It sounds like you'd be well served to use the producer/consumer pattern .NET 4 has built in to a few collections.
Check out page 55 in this free PDF from Microsoft, Patterns of Parallel Programming
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With