Как получить текущее запущенное задание в очереди блокировки C#?
Я хочу получить текущую задачу, которую я добавляю в очередь блокировки, как это можно сделать?
РЕДАКТИРОВАТЬ: я использую этот планировщик приоритетов и добавляю несколько задач с разными приоритетами:
public class PriorityScheduler : TaskScheduler
{
public static PriorityScheduler Highest = new PriorityScheduler(ThreadPriority.Highest);
public static PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal);
public static PriorityScheduler Normal = new PriorityScheduler(ThreadPriority.Normal);
public static PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal);
public static PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest);
public static 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
}
}
Я хочу, чтобы остановить и возобновить задачи в зависимости от их приоритетов, например, если приходит новая задача с более высоким приоритетом, нижняя останавливается и позволяет задаче выполнить, а затем возобновить себя...
1 ответ
Если вы имеете в виду BlockingCollection<T>
Вы не можете (напрямую). Когда вы звоните Take()
(или получите следующий товар через GetConsumingEnumerable()
), элемент (задача?) фактически удаляется из базового соединения.
Вам нужно будет иметь свой потребительский магазин и выставить "текущую задачу", если вы хотите, чтобы это было доступно.
Обратите внимание, что проект Parallel Extension Extras предоставляет отличный QueuedTaskScheduler, который может достичь ваших целей здесь. Это позволяет создавать приоритетные TaskScheduler
экземпляры, и обрабатывает все планирование для вас.