Wie andere haben erwähnt, müssen Sie einen benutzerdefinierten Scheduler für Ihre Aufgabe angeben. Leider gibt es keinen geeigneten integrierten Scheduler.
Sie könnten für die ParallelExtensionsExtras gehen, mit denen Glenn verbunden ist, aber wenn Sie etwas Einfaches wollen, das einfach direkt in Ihren Code eingefügt werden kann, versuchen Sie Folgendes. Verwenden Sie wie folgt aus:
Task.Factory.StartNew(() => {
// everything here will be executed in a thread whose priority is BelowNormal
}, null, TaskCreationOptions.None, PriorityScheduler.BelowNormal);
Der 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
}
}
Hinweise:
- Arbeitsthreads alle Hintergrund-Threads sind, so wichtige Aufgaben sollten nicht mit diesen Scheduler geplant werden; nur diejenigen, die verworfen werden können, wenn der Prozess herunterfährt
- angepasst von an implementation by Bnaya Eshet
- Ich verstehe nicht jede Überschreibung; gehen Sie einfach mit Bnayas Wahlen für
MaximumConcurrencyLevel
, GetScheduledTasks
und TryExecuteTaskInline
.
Ja, ich weiß über Thread.Priority. Aber ich wollte nur wissen, ob es mit Task Factory möglich war, Objekte von Thread zu verwenden. – Moon
Am ersten Link ist es eine Beschreibung, die besagt, dass es mit Task Factory nicht möglich ist.Jedenfalls muss ich nie die Priorität für Threads aus dem Pool ändern und nicht 100% sicher, dass es die Wahrheit ist. – zerkms