Stiamo eseguendo il porting dell'applicazione di modellazione, che utilizza gli script IronPython per le azioni personalizzate nel processo di modellazione. L'applicazione esistente esegue ciascuno script Python in un thread separato e utilizza il modello cooperativo per questo. Ora vogliamo portarlo su TPL, ma prima vogliamo misurare il cambio di contesto . In sostanza, quello che abbiamo in questo momento:Multitasking cooperativo con TPL
Task
s coda- ogni
Task
da questa coda esegue lo script uno IronPython - All'interno di script IronPython chiediamo C# metodo di classe, che è punto di sincronizzazione e dovrebbe trasferire
Task
(esecuzione IronPython) per stato di attesa
Quello che vogliamo fare:
- vogliamo fare loop infinito, che sarà scorrere
Task
s coda - quando arriviamo uno
Task
cerchiamo di eseguirlo - In PythonScript vogliamo chiamare C Metodo # e trasferire questo script per stato di attesa. ma non rimuoverlo dalla coda.
- Alla successiva iterazione quando otteniamo un altro
Task
controlliamo che sia in stato di attesa. se è così, lo svegliamo e proviamo a farlo. - In ogni momento si dovrebbe avere un solo attiva
Task
- E infine vogliamo misurare quanti
Task
potremmo eseguire al secondo
Io in realtà non so è qualcosa su multitasking cooperativo? Stiamo pensando all'abitudine TaskScheduler
, è un buon approccio? O qualcuno conosce una soluzione migliore?
Grazie.
Aggiornato:
Ok, così per esempio, non ho tale codice:
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();
}
}
personalizzati Utilità di pianificazione, ha una _thread
per l'esecuzione delle attività e _currentTask
campo per l'esecuzione di compiti, anche ha SleepCurrentTask
in questo metodo voglio sospendere l'esecuzione corrente del Task, ma non so come.
Codice cliente è semplice:
CancellationTokenSource tokenSource = new CancellationTokenSource();
Application app = Application.Create();
Task task = Task.Factory.StartNew(() =>
{
app.Scheduler.SleepCurrentTask();
},
tokenSource.Token, TaskCreationOptions.None, app.Scheduler);
}
Forse qualcuno ha un'idea migliore?