abaisser la priorité du fil Task.Factory.StartNew
-
26-09-2019 - |
Question
un code comme ci-dessous va commencer un nouveau thread pour faire le travail. Est-il possible que je peux contrôler la priorité de ce fil?
Task.Factory.StartNew(() => {
// everything here will be executed in a new thread.
// I want to set the priority of this thread to BelowNormal
});
La solution
Ceci est l'un des « ne pas faire » lorsque vous décidez si vous voulez pool de threads d'utilisation ou non; -)
Plus de détails ici: http://msdn.microsoft.com/en- nous / bibliothèque / 0ka9477y.aspx
Donc, la réponse est « Non, vous ne pouvez pas spécifier une priorité particulière pour le fil créé dans Theads Pool »
Au général taraudages Je parie que vous connaissez déjà propriété de Thread.Priority
Autres conseils
Comme d'autres l'ont mentionné, vous devez spécifier un planificateur personnalisé pour aller avec votre tâche. Malheureusement, il n'y a pas un programmateur intégré approprié.
Vous pouvez aller pour les ParallelExtensionsExtras que Glenn liée à, mais si vous voulez simplement quelque chose qui peut juste être 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, donc des tâches importantes ne doivent pas être planifiées à l'aide ce planificateur; seuls ceux qui peuvent être mis au rebut si les processus se ferme vers le bas
- adapté de une mise en œuvre par Bnaya Eshet
- Je ne comprends pas complètement tous les override; juste aller avec les choix de Bnaya pour
MaximumConcurrencyLevel
,GetScheduledTasks
etTryExecuteTaskInline
.
Priorité attribuée aux threads pour les tâches peut être réglé dans la méthode réelle qui exécute la tâche. Mais ne pas oublier de restaurer la priorité une fois que vous avez terminé pour éviter tout problème.
Alors d'abord démarrer la tâche:
new TaskFactory().StartNew(StartTaskMethod);
Ensuite, définir la priorité de fil:
void StartTaskMethod()
{
try
{
// Change the thread priority to the one required.
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
// Execute the task logic.
DoSomething();
}
finally
{
// Restore the thread default priority.
Thread.CurrentThread.Priority = ThreadPriority.Normal;
}
}
Lors du changement de priorité, garder à l'esprit ceci: Pourquoi * pas * modifier la priorité d'un fil ThreadPool (ou tâches)?
Pour la définition des priorités avec Task
, consultez les ordonnanceurs de tâches personnalisées décrites par Microsoft expert Stephen Toub ce blog MSDN . Pour plus de détails, ne manquez pas les liens vers les deux précédents messages qu'il mentionne dans la première phrase.
Pour votre problème, il semble que vous voudrez peut-être regarder le QueuedTaskScheduler
.