Comme d'autres ont mentionné, vous devez spécifier un planificateur personnalisé pour aller avec votre tâche. Malheureusement, il n'y a pas de planificateur intégré approprié.
Vous pouvez opter pour ParallelExtensionsExtras auquel Glenn est lié, mais si vous voulez que quelque chose de simple puisse être simplement collé directement dans votre code, essayez ce qui suit. Utilisez comme ceci:
Task.Factory.StartNew(() => {
// everything here will be executed in a thread whose priority is BelowNormal
}, null, TaskCreationOptions.None, PriorityScheduler.BelowNormal);
Le code:
public class PriorityScheduler : TaskScheduler
{
public static PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal);
public static PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal);
public static PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest);
private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
private Thread[] _threads;
private ThreadPriority _priority;
private readonly int _maximumConcurrencyLevel = Math.Max(1, Environment.ProcessorCount);
public PriorityScheduler(ThreadPriority priority)
{
_priority = priority;
}
public override int MaximumConcurrencyLevel
{
get { return _maximumConcurrencyLevel; }
}
protected override IEnumerable<Task> GetScheduledTasks()
{
return _tasks;
}
protected override void QueueTask(Task task)
{
_tasks.Add(task);
if (_threads == null)
{
_threads = new Thread[_maximumConcurrencyLevel];
for (int i = 0; i < _threads.Length; i++)
{
int local = i;
_threads[i] = new Thread(() =>
{
foreach (Task t in _tasks.GetConsumingEnumerable())
base.TryExecuteTask(t);
});
_threads[i].Name = string.Format("PriorityScheduler: ", i);
_threads[i].Priority = _priority;
_threads[i].IsBackground = true;
_threads[i].Start();
}
}
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false; // we might not want to execute task that should schedule as high or low priority inline
}
}
Notes:
- les threads de travail sont toutes les discussions de fond, ne doivent pas être des tâches planifiées si importantes en utilisant ce planificateur; seulement ceux qui peuvent être mis au rebut si le processus s'arrête
- adapté de an implementation by Bnaya Eshet
- Je ne comprends pas complètement chaque dérogation; juste aller avec les choix de Bnaya pour
MaximumConcurrencyLevel
, GetScheduledTasks
et TryExecuteTaskInline
.
Oui, je connais Thread.Priority. Mais je voulais juste savoir si c'était possible avec Task Factory au lieu d'utiliser des objets de Thread. – Moon
Au premier lien c'est une description qui dit que ce n'est pas possible avec Task Factory.De toute façon je n'ai jamais besoin de changer la priorité pour les threads de la piscine et je ne suis pas sûr à 100% que c'est la vérité. – zerkms