Мы переносим приложение моделирования, которое использует скрипты IronPython для настраиваемых действий в процессе моделирования. Существующее приложение выполняет каждый скрипт Python в отдельном потоке и использует для этого кооперативную модель. Теперь мы хотим перенести его на TPL, но сначала мы хотим измерить переключение контекста. . По сути, то, что у нас есть прямо сейчас:
Task
s queue Task
из этой очереди выполняет один скрипт IronPython Задачу
(выполнение IronPython) в состояние ожидания Что мы хотим сделать:
Задачу
s queue Task
, мы пытаемся выполнить ее Задачу
, мы проверяем, находится ли она в состоянии ожидания. если это так, мы разбудим его и попробуем выполнить.
Мы думаем о кастомном TaskScheduler
, это хороший подход? Или кто-то знает лучшее решение?
Спасибо.
Обновлено:
Хорошо, например, у меня есть такой код:
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, у него есть один _thread
для Task Execution и поле _currentTask
для запущенной задачи, также у него есть SleepCurrentTask
в этом методе. Я хочу приостановить выполнение текущей задачи, но я не знаю как.
Клиентский код прост :
CancellationTokenSource tokenSource = new CancellationTokenSource();
Application app = Application.Create();
Task task = Task.Factory.StartNew(() =>
{
app.Scheduler.SleepCurrentTask();
},
tokenSource.Token, TaskCreationOptions.None, app.Scheduler);
}
Может быть, у кого-то есть идеи получше?